ASDisplayNode.mm
_locked_applyPendingStateToViewOrLayer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)_locked_applyPendingStateToViewOrLayer
{
ASDisplayNodeAssertMainThread();
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssert(self.nodeLoaded, @"must have a view or layer");
TIME_SCOPED(_debugTimeToApplyPendingState);
// If no view/layer properties were set before the view/layer were created, _pendingViewState will be nil and the default values
// for the view/layer are still valid.
[self _locked_applyPendingViewState];
if (_flags.displaySuspended) {
self._locked_asyncLayer.displaySuspended = YES;
}
if (!_flags.displaysAsynchronously) {
self._locked_asyncLayer.displaysAsynchronously = NO;
}
}
applyPendingViewState
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (void)applyPendingViewState
{
ASDisplayNodeAssertMainThread();
ASAssertUnlocked(__instanceLock__);
AS::UniqueLock l(__instanceLock__);
// FIXME: Ideally we'd call this as soon as the node receives -setNeedsLayout
// but automatic subnode management would require us to modify the node tree
// in the background on a loaded node, which isn't currently supported.
if (_pendingViewState.hasSetNeedsLayout) {
// Need to unlock before calling setNeedsLayout to avoid deadlocks.
l.unlock();
[self __setNeedsLayout];
l.lock();
}
[self _locked_applyPendingViewState];
}
_locked_applyPendingViewState
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (void)_locked_applyPendingViewState
{
ASDisplayNodeAssertMainThread();
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssert([self _locked_isNodeLoaded], @"Expected node to be loaded before applying pending state.");
if (_flags.layerBacked) {
[_pendingViewState applyToLayer:_layer];
} else {
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesHandling(checkFlag(Synchronous), _flags.layerBacked);
[_pendingViewState applyToView:_view withSpecialPropertiesHandling:specialPropertiesHandling];
}
// _ASPendingState objects can add up very quickly when adding
// many nodes. This is especially an issue in large collection views
// and table views. This needs to be weighed against the cost of
// reallocing a _ASPendingState. So in range managed nodes we
// delete the pending state, otherwise we just clear it.
if (ASHierarchyStateIncludesRangeManaged(_hierarchyState)) {
_pendingViewState = nil;
} else {
[_pendingViewState clearChanges];
}
}
_supernodeWithClass: checkViewHierarchy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (ASDisplayNode *)_supernodeWithClass:(Class)supernodeClass checkViewHierarchy:(BOOL)checkViewHierarchy
{
ASDisplayNode *supernode = self.supernode;
while (supernode) {
if ([supernode isKindOfClass:supernodeClass])
return supernode;
supernode = supernode.supernode;
}
if (!checkViewHierarchy) {
return nil;
}
UIView *view = self.view.superview;
while (view) {
ASDisplayNode *viewNode = ((_ASDisplayView *)view).asyncdisplaykit_node;
if (viewNode) {
if ([viewNode isKindOfClass:supernodeClass])
return viewNode;
}
view = view.superview;
}
return nil;
}