Initial experimental commit with functioning preloading, without the working window.

This commit is contained in:
Scott Goodson
2015-11-08 12:56:17 -08:00
committed by Scott Goodson
parent 771eca5083
commit 7f59beb195
6 changed files with 56 additions and 10 deletions

View File

@@ -62,6 +62,29 @@
}
}
- (void)clearFetchedData
{
[super clearFetchedData];
NSLog(@"%p - clearFetchedData", self);
}
- (void)fetchData
{
[super fetchData];
NSLog(@"%p - fetchData", self);
}
- (void)clearContents
{
[super clearContents];
NSLog(@"%p - clearContents", self);
}
- (void)dealloc
{
NSLog(@"%p - dealloc", self);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();

View File

@@ -665,7 +665,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
[self _addSubnodeViewsAndLayers];
}
[self recursivelyDisplayImmediately];
[self recursivelyEnsureDisplay];
}
}
@@ -1454,8 +1454,8 @@ void recursivelyEnsureDisplayForLayer(CALayer *layer)
- (void)recursivelyEnsureDisplay
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(self.isNodeLoaded, @"Node must have layer or view loaded to use -recursivelyEnsureDisplay");
ASDisplayNodeAssert(self.inHierarchy && (self.isLayerBacked || self.view.window != nil), @"Node must be in a hierarchy to use -recursivelyEnsureDisplay");
// ASDisplayNodeAssert(self.isNodeLoaded, @"Node must have layer or view loaded to use -recursivelyEnsureDisplay");
// ASDisplayNodeAssert(self.inHierarchy && (self.isLayerBacked || self.view.window != nil), @"Node must be in a hierarchy to use -recursivelyEnsureDisplay");
CALayer *layer = self.layer;
// -layoutIfNeeded is recursive, and even walks up to superlayers to check if they need layout,

View File

@@ -12,13 +12,16 @@
#import "ASDisplayNode+Subclasses.h"
#import "ASDisplayNodeInternal.h"
#define USE_WORKING_WINDOW 0
@interface ASRangeHandlerRender ()
@property (nonatomic,readonly) UIWindow *workingWindow;
@end
@implementation ASRangeHandlerRender
@synthesize workingWindow = _workingWindow;
#if USE_WORKING_WINDOW
@synthesize workingWindow = _workingWindow;
- (UIWindow *)workingWindow
{
ASDisplayNodeAssertMainThread();
@@ -45,6 +48,7 @@
[self node:node exitedRangeOfType:ASLayoutRangeTypeRender];
}
}
#endif
- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
{
@@ -60,12 +64,17 @@
// The node un-suspends display.
[node enterInterfaceState:ASInterfaceStateDisplay];
#if USE_WORKING_WINDOW
// Add the node's layer to an off-screen window to trigger display and mark its contents as non-volatile.
// Use the layer directly to avoid the substantial overhead of UIView heirarchy manipulations.
// Any view-backed nodes will still create their views in order to assemble the layer heirarchy, and they will
// also assemble a view subtree for the node, but we avoid the much more significant expense triggered by a view
// being added or removed from an onscreen window (responder chain setup, will/DidMoveToWindow: recursive calls, etc)
[[[self workingWindow] layer] addSublayer:node.layer];
#else
[node recursivelyEnsureDisplay]; // Need to do this without waiting
#endif
}
- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
@@ -93,6 +102,7 @@
// The node calls clearCurrentContents and suspends display
[node exitInterfaceState:ASInterfaceStateDisplay];
#if USE_WORKING_WINDOW
if (node.layer.superlayer != [[self workingWindow] layer]) {
// In this case, the node has previously passed through the working range (or it is zero), and it has now fallen outside the working range.
if (![node isLayerBacked]) {
@@ -104,6 +114,13 @@
// At this point, the node's layer may validly be present either in the workingWindow, or in the contentsView of a cell.
[node.layer removeFromSuperlayer];
#else
if (![node isLayerBacked]) {
[node.view removeFromSuperview];
} else {
[node.layer removeFromSuperlayer];
}
#endif
}
@end

View File

@@ -146,11 +146,9 @@
- (void)displayImmediately
{
// REVIEW: Should this respect isDisplaySuspended? If so, we'd probably want to synchronously display when
// setDisplaySuspended:No is called, rather than just scheduling. The thread affinity for the displayImmediately
// call will be tricky if we need to support this, though. It probably should just execute if displayImmediately is
// called directly. The caller should be responsible for not calling displayImmediately if it wants to obey the
// suspended state.
// This method is a low-level bypass that avoids touching CA, including any reset of the
// needsDisplay flag, until the .contents property is set with the result.
// It is designed to be able to block the thread of any caller and fully execute the display.
ASDisplayNodeAssertMainThread();
[self display:NO];

View File

@@ -111,7 +111,7 @@ typedef NS_ENUM(NSUInteger, PIDebugBoxPaddingLocation)
[paddedLines addObject:paddedLine];
}
concatenatedLines = paddedLines;
totalLineLength += difference;
// totalLineLength += difference;
}
concatenatedLines = [self appendTopAndBottomToBoxString:concatenatedLines parent:parent];
return [concatenatedLines componentsJoinedByString:@"\n"];

View File

@@ -223,6 +223,14 @@
[rasterizedContainerNode setNeedsDisplay];
} else {
[_layer setNeedsDisplay];
if (_layer && !self.isSynchronous && self.displaysAsynchronously) {
// It's essenital that any layout pass that is scheduled during the current
// runloop has a chance to be applied / scheduled.
dispatch_async(dispatch_get_main_queue(), ^{
[self recursivelyEnsureDisplay];
});
}
}
}