Use this array while enumerating ASRangeController instances in response to UIApplication notifications,
as it is possible for these events to trigger the mutation of the ASWeakSet and cause an enumeration error.
Introduces ASLayoutRangeModeVisibleOnly, allowing the preservation of decoded backing stores without any extra padding to
strictly minimize memory usage while supporting immediate re-display of content. Set visible range controllers to this mode
upon app suspend / memory warning, while more aggressively clearing others to the ASLayoutRangeModeLowMemory mode.
By default, when the app is running and recieves a memory warning, we set the range mode for non-visible controllers to
ASLayoutRangeModeVisibleOnly. This is because, unlike in the app suspend case where on app resume we can restore controllers
from LowMemory to VisibleOnly, the memory warning doesn't provide a good opportunity to do this.
A new +Beta API to control this behavior is called +setRangeModeForMemoryWarnings:, as some apps may prefer to use LowMemory
in the memory warning scenario. For these apps, optimal user experience will require manually setting the range mode back
to some larger value as the user navigates the app, or they will encounter controllers that are temporarily blank and need
a moment to re-display their contents as they start to become visible.
Locking was not quite right here in a certain case where the transaction leaves after other references
were removed. Will restore this optimization in the future with more time to analyze.
This reverts commit ee524f497d.
- These calls cause supplementary nodes to be allocated and laid out, but not inserted afterward. So the nodes are thrown away.
- Next time when it is the right time to allocate these nodes, it is the second allocation request and triggers assertion in ASIndexedNodeContext #1296.
- _populateFromDataSourceWithSectionIndexSet doesn't accept a mutanle array but allocate one itself.
- Remove _populateFromEntireDataSourceWithMutableContexts.
- ASIndexedNodeContext executes its block, nil out the block and return the result.
- It is a container object that holds enough information to construct and measure a cell node
- All information is gathered on main thread. This allows ASDataController to capture the correct state of its data source before going to background.
These optimizations are surprisingly impactful. -setNeedsDisplay being called
for every node triggered cancelAsyncDisplay, locking, and memory management overhead
that is completely avoidable because Core Animation triggers first display automatically.
The mutable array copy optimizations reduced this key cost by over 10x, from 52ms to 5ms
on an iPad Air 2 / A8X with a real-world test case.
The optimization seems correct now, but apps like Pinterest have some core code relying on edit operation
order that is actually not permitted by UIKit (and this diff) but were tolerated previously. We will
re-land this once we have time to adapt the code.