Oleg Andreev



Software designer with focus on user experience and security.

You may start with my selection of articles on Bitcoin.

Переводы некоторых статей на русский.



Product architect at Chain.

Author of Gitbox version control app.

Author of CoreBitcoin, a Bitcoin toolkit for Objective-C.

Author of BTCRuby, a Bitcoin toolkit for Ruby.

Former lead dev of FunGolf GPS, the best golfer's personal assistant.



I am happy to give you an interview or provide you with a consultation.
I am very interested in innovative ways to secure property and personal interactions: all the way from cryptography to user interfaces. I am not interested in trading, mining or building exchanges.

This blog enlightens people thanks to your generous donations: 1TipsuQ7CSqfQsjA9KU5jarSB1AnrVLLo

The efficient way to load and render images in the UITableViewCell

Suppose you have that kind of user interface:

The efficient rendering algorithm would be the following:

1. Cell should render its content manually: that is not using multiple views, but using a single contentView which is updated programmatically in drawInRect: method.

2. Each time cell is rendered, it checks the cache of downloaded images. If image is not present, cell schedules request to download it. Cell should remember the request URL to be notified when data is ready.

3. Download request goes to FILO queue with async NSURLConnection delegate. Async API uses the main thread which is notified when data is ready.

4. The queue size should be limited by a maximum number of visible cells. The most recently requested images go to the end of the queue, while the head of the queue is truncated each time new request is added. This way scheduled requests are removed when corresponding cells become invisible.

5. Download callback should lookup [tableView visibleCells] to find the exact cell which requests the downloaded image. The cell could be different than the one started the request (remember cell recycling!). You cannot just call [tableView reloadData]: it works poorly when a lot of images are loaded while you scroll.

6. In addition to downloaded images cache, there should be pre-rendered images cache: each time cell draws itself and finds the downloaded image, it should rescale and crop the image. The rescaled image should be put in the cache, otherwise scrolling won’t be smooth. Of course, if the downloaded image is already sized as needed, this step could be omitted. See UIGraphicsBeginImageContext.

Toolkit summary:

— download requests queue with async i/o (no NSOperations, no background threads)
— manual cell rendering (no subviews)
— individual cell update (do not reloadData)
— pre-rendered images cache
— discard pending downloads for invisible cells

Gravitational Garbage Collector
Unreachable objects and whole cycles fall on a ground immediately. The ground is eventually scanned and cleaned-up.
Pros: incremental, concurrent, localized.
Cons: gravity simulation might consume up to 99% of CPU...

Gravitational Garbage Collector

Unreachable objects and whole cycles fall on a ground immediately. The ground is eventually scanned and cleaned-up.

Pros: incremental, concurrent, localized.
Cons: gravity simulation might consume up to 99% of CPU time.

Paper: on-the-fly reference-counting GC

Reference-counting is traditionally considered unsuitable for multi-processor systems. According to conventional wisdom, the update of reference slots and reference-counts requires atomic or synchronized operations. In this work we demonstrate this is not the case by presenting a novel reference-counting algorithm suitable for a multi-processor system that does not require any syn- chronized operation in its write barrier (not even a compare-and-swap type of synchronization). A second novelty of this algorithm is that it allows eliminating a large fraction of the reference- count updates, thus, drastically reducing the reference-counting traditional overhead. This paper includes a full proof of the algorithm showing that it is safe (does not reclaim live objects) and live (eventually reclaims all unreachable objects).

refcount.pdf

Notes on garbage collectors

1. Some GCs do pointer recognition in the arbitrary data array (e.g. Boehm-Demers-Weiser GC); this is not necessary if GC should track objects of the known structure (e.g. Steve Dekorte’s GC)

2. If we track object references only, there’s no need to fight fragmentation of the GC-managed heap: all entries are of the same size.

3. After coding Obj-C for a while, I’ve noticed that the only issue which should be resolved by some kind of garbage collector is circular references. Retained properties and autorelease pools already help to avoid manual retain/release calls. That is: allocation should be always succeeded by autorelease and all the properties should be nullified on deallocation (this could be done automatically).

I wonder if it is possible to use a simple reference-counting mechanism with a simple referential cycles resolution, thinking that way we can imagine a very simple and efficient garbage collector.

References:
1. Minimizing Reference Count Updating with Deferred and
Anchored Pointers for Functional Data Structures
by Henry Baker
2. Concurrent Cycle Collection in Reference Counted Systems by David F. Bacon and V.T. Rajan

Build configurations for the real world iPhone app with in-app purchases (in-app product is a time-limited subscription):
Debug — uses localhost;
Debug sandboxing storekit — tells server to use sandbox verification URL;
Debug bypassing storekit —...

Build configurations for the real world iPhone app with in-app purchases (in-app product is a time-limited subscription):

Debug — uses localhost;

Debug sandboxing storekit — tells server to use sandbox verification URL;

Debug bypassing storekit — ignores storekit and assumes subscription is always valid;

Debug simulated storekit — substitutes SK* classes with our in-house mocks, allows testing on Simulator and localhost;

Debug simulated storekit + restored transactions — same as above + allows restoring valid subscriptions;

Release bypassing storekit — uses real host, but ignores storekit and assumes subscription is always valid;

Release sandboxing storekit — uses real host, tells the server to use sandbox verification URL;

Release — regular release config (obsolete; we are using “Release sandboxing storekit” instead);

Distribution — config for AppStore publishing.

Note: I have written simulated storekit classes when we experienced iTunes Connect outage and “add new sandbox user” form issues.

Note-2: Each non-release configuration issues a #warning in every place where some non-shippable value is used (e.g. localhost, hardcoded default location, storekit substitution)

StoreKit in-app purchases: lessons learned

1. When using sandbox user account, do not sign in using Preferences, just sign out and sign in when your app asks so.
2. Transaction receipt should be Base64 encoded before sending to Apple verification service. This is not mentioned in the docs.
3. Subscriptions should not be restored using restore API. Do not even try: Apple suggests sending relevant data from your application server.
4. Title/description you set in iTunes connect do not really matter if you supply products from the server. Only product id and the price tier matter. Everything else you supply by yourself.
5. Do not forget to sort the products elsewhere since it is impossible to sort them on iTunes Connect site.
6. Transaction receipt should be verified at apple server for two reasons: 1) secure validation; 2) this is the only way to get transaction details