* Always layout nodes on a background thread
* Remove semaphore in ASDataController for allocating nodes and layout
* Fix variable not used error
* Remove overhead to create subarray of contexts of nodes while layout nodes
* Remove extra allocation of allocatedNodes and indexPaths array
This situation is relatively uncommon. If a user manually uses -[UIView addSubnode:], the convenience category method,
and then calls -[ASDisplayNode removeFromSuperview] -- we would bypass performing the actual removal as no supernode pointer
is set. After further consideration, the special handling here to support divergence between the supernode pointer and
the view / layer hierarchy is not something we need to maintain going forward, and removing it makes addressing this easy.
Currently measurement always needs to happen on the main thread if implicit hierarchy management is enabled as adding and removing from nodes needs to happen on the main thread. We now will trampoline to the main thread to do the insertion and deletion of nodes.
This also resolves the issue that can occur if a node is already loaded deep in the layout hierarchy in the layout that the node is transforming to. Before insertion or deletion is happening we need to crawl the layout hierarchy to check that though.
I looked into the internals of UIImageView a bit. I would recommend to not fixing this in a universal way. UIImageView is specifically optimized for performance and does not use the usual way to provide the contents of the CALayer that backs the UIImageView.
Furthermore we cannot trigger a recreation of the contents of the UIImageView layer as if it get’s cleared and we call setNeedsDisplay on it it goes trough the normal flow to assign the contents to a layer via the CALayerDelegate methods. Unfortunately UIImageView does not do it, it actually does not implement some of the methods at all, so nothing will show up. It’s getting better, by calling setNeedsDisplay on an UIImageView layer it actually clears the contents and nothing is visible anymore. So we have to be careful to not calling that too.
Unfortunately I didn’t find a way yet to trigger a recreation of the UIImageView layers content except calling the private _updateState method.
That said it’s different for layers of other UIKit components like UILabel for example. Clearing the contents of a UILabel layer and calling setNeedsDisplay on the layer usually recreates the contents of the it and it will show up again.
This commit prevents to clear the contents of a layer for all wrapped UIKit and instead only NOT clear the content if the node wraps a UIImageView otherwise we should clear the contents of the layer to reclaim memory as usual.
If a developer makes this error, it would prevent calls to key lifecycle methods, such as -layoutSpecThatFits:.
Although the superclasses of ASDisplayNode do not implement +initialize, a super call is added here for consistency.
Normally measure will be called before layout occurs. If this doesn't happen, nothing is going to call it at all. An experimenting developer probably added a node to the hierarchy directly. We simply call measureWithSizeRange: using a size range equal to whatever bounds were provided to that element. This make initial experimentation using layoutSpecs much easier. Furthermore added logging if no size is given for the node before layout occurs.