Speculative fix for #380. Calling `-[ASImageNode setImage:]` on a
background queue will take the image lock, then trampoline to the main
queue to invalidate calculatedSize and set needsDisplay without
releasing the lock. Any other method call that takes the image lock on
the main queue can block on the trampoline completing -- deadlock.
Note that the trampoline is itself a clowny workaround for thread
affinity (#134) and should be removed. With this patch applied,
ASImageNode's `-setImage:` and `-calculateSizeThatFits:` can still race:
1. -setImage changes _image, then trampolines to main
2. -calculateSizeThatFits measures _image
3. trampoline completes, invalidates calculated size
4. ???
5. ~~profit!~~ 💥
ASImageNodeTint is inflexible (your options are "no tint" and "use
`[UIColor grayColor]`") and needlessly complicates the ASImageNode
implementation. Use ASImageNodeTintColorModificationBlock() instead.
Closes#383.
This brings back the concept of a window store for nodes that are in the working range (reverting #127). It turns out that due to the system architecture if there are nodes who fetch remote content (e.g. `ASNetworkImageNode`), calls to `-display` will occur before fetching has been completed. The next chance the nodes have to decode and display content is then when they are actually on the screen, thus defeating the purpose of a working range.
With the reintroduction of the working range window, nodes are "stored" in the window and when content is finished being fetched, CA triggers `-display` since they are part of a view hierarchy.
This can be tested in the Kittens project by insuring that before `ASRangeController` adds a node to [a visible view](https://github.com/facebook/AsyncDisplayKit/blob/master/AsyncDisplayKit/Details/ASRangeController.mm#L57) that the image node (with remote content) has set its layer's contents.
Summary:
What it says on the tin. This allows Nodes to effectively participate in the responder chain.
Caveat: see note in implementation below. Would have been nice to use `-targetForAction:withSender:` the way the docs imply you can, but alas.
Test Plan: Observe a node in the responder chain get invoked to handle an action it implements.
Reviewers: bcunning, zsh, sma, jpasqualini, suv, nyn531, b3ll, aaronpang, kimon, grp, jonathan, rnystrom, nadi
Reviewed By: nadi
Subscribers: trunkagent, rnystrom
Differential Revision: https://phabricator.fb.com/D1894023
Signature: t1:1894023:1426026643:203945b6a7c318f6d2c9b94d876da61da31327bd
This is a step towards a preloading range. We first want to migrate towards arbitrary ranges instead of being coupled to the notion of a single "working range".