Skip to content

Commit 8ec4b31

Browse files
authored
Overhaul our logging, add activity tracing support. (TextureGroup#399)
* Improve the os_log and os_activity integration * Address feedback from Scott and Huy
1 parent 2cda73a commit 8ec4b31

44 files changed

Lines changed: 708 additions & 266 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AsyncDisplayKit.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@
376376
CCA282D01E9EBF6C0037E8B7 /* ASTipsWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */; };
377377
CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */; };
378378
CCA5F62E1EECC2A80060C137 /* ASAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA5F62D1EECC2A80060C137 /* ASAssert.m */; };
379+
CCB1F95A1EFB60A5009C7475 /* ASLog.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB1F9591EFB60A5009C7475 /* ASLog.m */; };
380+
CCB1F95C1EFB6350009C7475 /* ASSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = CCB1F95B1EFB6316009C7475 /* ASSignpost.h */; };
379381
CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */; };
380382
CCBBBF5D1EB161760069AA91 /* ASRangeManagingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
381383
CCCCCCD51EC3EF060087FE10 /* ASTextDebugOption.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCC31EC3EF060087FE10 /* ASTextDebugOption.h */; };
@@ -842,6 +844,8 @@
842844
CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipsWindow.h; sourceTree = "<group>"; };
843845
CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTipsWindow.m; sourceTree = "<group>"; };
844846
CCA5F62D1EECC2A80060C137 /* ASAssert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASAssert.m; sourceTree = "<group>"; };
847+
CCB1F9591EFB60A5009C7475 /* ASLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLog.m; sourceTree = "<group>"; };
848+
CCB1F95B1EFB6316009C7475 /* ASSignpost.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASSignpost.h; sourceTree = "<group>"; };
845849
CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeSnapshotTests.m; sourceTree = "<group>"; };
846850
CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeManagingNode.h; sourceTree = "<group>"; };
847851
CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIGListAdapterBasedDataSource.m; sourceTree = "<group>"; };
@@ -1387,6 +1391,8 @@
13871391
058D0A44195D058D00B7D73C /* ASBaseDefines.h */,
13881392
1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */,
13891393
0516FA3B1A15563400B4EBED /* ASLog.h */,
1394+
CCB1F9591EFB60A5009C7475 /* ASLog.m */,
1395+
CCB1F95B1EFB6316009C7475 /* ASSignpost.h */,
13901396
);
13911397
path = Base;
13921398
sourceTree = "<group>";
@@ -1692,6 +1698,7 @@
16921698
9019FBBF1ED8061D00C45F72 /* ASYogaUtilities.h in Headers */,
16931699
DE84918D1C8FFF2B003D89E9 /* ASRunLoopQueue.h in Headers */,
16941700
CC0F88621E4281E200576FED /* ASSectionController.h in Headers */,
1701+
CCB1F95C1EFB6350009C7475 /* ASSignpost.h in Headers */,
16951702
A2763D7A1CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h in Headers */,
16961703
34EFC7611B701C9C00AD841F /* ASBackgroundLayoutSpec.h in Headers */,
16971704
B35062591B010F070018CF92 /* ASBaseDefines.h in Headers */,
@@ -2180,6 +2187,7 @@
21802187
B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */,
21812188
8021EC1F1D2B00B100799119 /* UIImage+ASConvenience.m in Sources */,
21822189
B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */,
2190+
CCB1F95A1EFB60A5009C7475 /* ASLog.m in Sources */,
21832191
767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.m in Sources */,
21842192
CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.m in Sources */,
21852193
34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */,

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
- [ASTextNode2] Add initial implementation for link handling. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/396)
55
- [ASTextNode2] Provide compile flag to globally enable new implementation of ASTextNode: ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/410)
66

7+
##2.3.5
8+
- Fix an issue where inserting/deleting sections could lead to inconsistent supplementary element behavior. [Adlai Holler](https://github.com/Adlai-Holler)
9+
- Overhaul logging and add activity tracing support. [Adlai Holler](https://github.com/Adlai-Holler)
10+
711
##2.3.4
812
- [Yoga] Rewrite YOGA_TREE_CONTIGUOUS mode with improved behavior and cleaner integration [Scott Goodson](https://github.com/appleguy)
913
- [ASTraitCollection] Convert ASPrimitiveTraitCollection from lock to atomic. [Scott Goodson](https://github.com/appleguy)
@@ -15,7 +19,6 @@
1519
- Migrated unit tests to OCMock 3.4 (from 2.2) and improved the multiplex image node tests. [Adlai Holler](https://github.com/Adlai-Holler)
1620
- Fix CollectionNode double-load issue. This should significantly improve performance in cases where a collection node has content immediately available on first layout i.e. not fetched from the network. [Adlai Holler](https://github.com/Adlai-Holler)
1721
- Overhaul layout flattening algorithm [Huy Nguyen](https://github.com/nguyenhuy) [#395](https://github.com/TextureGroup/Texture/pull/395).
18-
- Fix an issue where inserting/deleting sections could lead to inconsistent supplementary element behavior. [Adlai Holler](https://github.com/Adlai-Holler)
1922

2023
## 2.3.3
2124
- [ASTextKitFontSizeAdjuster] Replace use of NSAttributedString's boundingRectWithSize:options:context: with NSLayoutManager's boundingRectForGlyphRange:inTextContainer: [Ricky Cancro](https://github.com/rcancro)

Source/ASCellNode.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,13 @@ - (void)handleVisibilityChange:(BOOL)isVisible
315315
if (ip != nil) {
316316
[result addObject:@{ @"indexPath" : ip }];
317317
}
318-
[result addObject:@{ @"collectionNode" : ASObjectDescriptionMakeTiny(owningNode) }];
318+
[result addObject:@{ @"collectionNode" : owningNode }];
319319
} else if ([owningNode isKindOfClass:[ASTableNode class]]) {
320320
NSIndexPath *ip = [(ASTableNode *)owningNode indexPathForNode:self];
321321
if (ip != nil) {
322322
[result addObject:@{ @"indexPath" : ip }];
323323
}
324-
[result addObject:@{ @"tableNode" : ASObjectDescriptionMakeTiny(owningNode) }];
324+
[result addObject:@{ @"tableNode" : owningNode }];
325325

326326
} else if ([scrollView isKindOfClass:[ASCollectionView class]]) {
327327
NSIndexPath *ip = [(ASCollectionView *)scrollView indexPathForNode:self];

Source/ASCollectionView.mm

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ - (void)beginUpdates
800800

801801
if (_batchUpdateCount == 0) {
802802
_changeSet = [[_ASHierarchyChangeSet alloc] initWithOldData:[_dataController itemCountsFromDataSource]];
803+
_changeSet.rootActivity = as_activity_create("Perform async collection update", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
804+
_changeSet.submitActivity = as_activity_create("Submit changes for collection update", _changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT);
803805
}
804806
_batchUpdateCount++;
805807
}
@@ -817,6 +819,7 @@ - (void)endUpdatesAnimated:(BOOL)animated completion:(nullable void (^)(BOOL))co
817819

818820
if (_batchUpdateCount == 0) {
819821
_ASHierarchyChangeSet *changeSet = _changeSet;
822+
820823
// Nil out _changeSet before forwarding to _dataController to allow the change set to cause subsequent batch updates on the same run loop
821824
_changeSet = nil;
822825
changeSet.animated = animated;
@@ -828,8 +831,13 @@ - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completi
828831
{
829832
ASDisplayNodeAssertMainThread();
830833
[self beginUpdates];
831-
if (updates) {
832-
updates();
834+
as_activity_scope(_changeSet.rootActivity);
835+
{
836+
// Only include client code in the submit activity, the rest just lives in the root activity.
837+
as_activity_scope(_changeSet.submitActivity);
838+
if (updates) {
839+
updates();
840+
}
833841
}
834842
[self endUpdatesAnimated:animated completion:completion];
835843
}
@@ -1575,10 +1583,12 @@ - (void)_beginBatchFetchingIfNeededWithContentOffset:(CGPoint)contentOffset velo
15751583

15761584
- (void)_beginBatchFetching
15771585
{
1586+
as_activity_create_for_scope("Batch fetch for collection node");
15781587
[_batchContext beginBatchFetching];
15791588
if (_asyncDelegateFlags.collectionNodeWillBeginBatchFetch) {
15801589
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
15811590
GET_COLLECTIONNODE_OR_RETURN(collectionNode, (void)0);
1591+
as_log_debug(ASCollectionLog(), "Beginning batch fetch for %@ with context %@", collectionNode, _batchContext);
15821592
[_asyncDelegate collectionNode:collectionNode willBeginBatchFetchWithContext:_batchContext];
15831593
});
15841594
} else if (_asyncDelegateFlags.collectionViewWillBeginBatchFetch) {
@@ -1894,9 +1904,11 @@ - (void)rangeController:(ASRangeController *)rangeController didUpdateWithChange
18941904
}
18951905

18961906
ASPerformBlockWithoutAnimation(!changeSet.animated, ^{
1897-
if(changeSet.includesReloadData) {
1907+
as_activity_scope(as_activity_create("Commit collection update", changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT));
1908+
if (changeSet.includesReloadData) {
18981909
_superIsPendingDataLoad = YES;
18991910
[super reloadData];
1911+
as_log_debug(ASCollectionLog(), "Did reloadData %@", self.collectionNode);
19001912
[changeSet executeCompletionHandlerWithFinished:YES];
19011913
} else {
19021914
[_layoutFacilitator collectionViewWillPerformBatchUpdates];
@@ -1933,13 +1945,17 @@ - (void)rangeController:(ASRangeController *)rangeController didUpdateWithChange
19331945
numberOfUpdates++;
19341946
}
19351947
} completion:^(BOOL finished){
1948+
as_activity_scope(as_activity_create("Handle collection update completion", changeSet.rootActivity, OS_ACTIVITY_FLAG_DEFAULT));
1949+
as_log_verbose(ASCollectionLog(), "Update animation finished %{public}@", self.collectionNode);
19361950
// Flush any range changes that happened as part of the update animations ending.
19371951
[_rangeController updateIfNeeded];
19381952
[self _scheduleCheckForBatchFetchingForNumberOfChanges:numberOfUpdates];
19391953
[changeSet executeCompletionHandlerWithFinished:finished];
19401954
}];
1955+
as_log_debug(ASCollectionLog(), "Completed batch update %{public}@", self.collectionNode);
19411956

19421957
// Flush any range changes that happened as part of submitting the update.
1958+
as_activity_scope(changeSet.rootActivity);
19431959
[_rangeController updateIfNeeded];
19441960
}
19451961
});

Source/ASDisplayNode+Layout.mm

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#import <AsyncDisplayKit/ASInternalHelpers.h>
1616
#import <AsyncDisplayKit/ASLayout.h>
1717
#import <AsyncDisplayKit/ASLayoutElementStylePrivate.h>
18+
#import <AsyncDisplayKit/ASLog.h>
1819

1920
#import <AsyncDisplayKit/ASDisplayNode+FrameworkSubclasses.h>
2021

@@ -127,25 +128,20 @@ - (ASTraitCollection *)asyncTraitCollection
127128

128129
ASPrimitiveTraitCollectionDeprecatedImplementation
129130

130-
@end
131-
132-
#pragma mark -
133131
#pragma mark - ASLayoutElementAsciiArtProtocol
134132

135-
@implementation ASDisplayNode (ASLayoutElementAsciiArtProtocol)
136-
137133
- (NSString *)asciiArtString
138134
{
139135
return [ASLayoutSpec asciiArtStringForChildren:@[] parentName:[self asciiArtName]];
140136
}
141137

142138
- (NSString *)asciiArtName
143139
{
144-
NSString *string = NSStringFromClass([self class]);
140+
NSMutableString *result = [NSMutableString stringWithCString:object_getClassName(self) encoding:NSASCIIStringEncoding];
145141
if (_debugName) {
146-
string = [string stringByAppendingString:[NSString stringWithFormat:@"\"%@\"",_debugName]];
142+
[result appendFormat:@" (%@)", _debugName];
147143
}
148-
return string;
144+
return result;
149145
}
150146

151147
@end
@@ -222,6 +218,7 @@ @implementation ASDisplayNode (ASLayoutInternal)
222218
*/
223219
- (void)_setNeedsLayoutFromAbove
224220
{
221+
as_activity_create_for_scope("Set needs layout from above");
225222
ASDisplayNodeAssertThreadAffinity(self);
226223

227224
// Mark the node for layout in the next layout pass
@@ -315,6 +312,8 @@ - (void)_locked_measureNodeWithBoundsIfNecessary:(CGRect)bounds
315312
}
316313
}
317314

315+
as_activity_create_for_scope("Update node layout for current bounds");
316+
as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", self, NSStringFromCGSize(boundsSizeForLayout), NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), _calculatedDisplayNodeLayout->isDirty());
318317
// _calculatedDisplayNodeLayout is not reusable we need to transition to a new one
319318
[self cancelLayoutTransition];
320319

@@ -332,7 +331,20 @@ - (void)_locked_measureNodeWithBoundsIfNecessary:(CGRect)bounds
332331

333332
// nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied.
334333
// If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr->
335-
if (nextLayout == nullptr || nextLayout->isDirty() == YES || layoutSizeDifferentFromBounds) {
334+
BOOL pendingLayoutApplicable = NO;
335+
if (nextLayout == nullptr) {
336+
as_log_verbose(ASLayoutLog(), "No pending layout.");
337+
} else if (nextLayout->isDirty()) {
338+
as_log_verbose(ASLayoutLog(), "Pending layout is invalid.");
339+
} else if (layoutSizeDifferentFromBounds) {
340+
as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size));
341+
} else {
342+
as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout->layout);
343+
pendingLayoutApplicable = YES;
344+
}
345+
346+
if (!pendingLayoutApplicable) {
347+
as_log_verbose(ASLayoutLog(), "Measuring with previous constrained size.");
336348
// Use the last known constrainedSize passed from a parent during layout (if never, use bounds).
337349
ASSizeRange constrainedSize = [self _locked_constrainedSizeForLayoutPass];
338350
ASLayout *layout = [self calculateLayoutThatFits:constrainedSize
@@ -350,6 +362,7 @@ - (void)_locked_measureNodeWithBoundsIfNecessary:(CGRect)bounds
350362
// This can occur for either pre-calculated or newly-calculated layouts.
351363
if (nextLayout->requestedLayoutFromAbove == NO
352364
&& CGSizeEqualToSize(boundsSizeForLayout, nextLayout->layout.size) == NO) {
365+
as_log_verbose(ASLayoutLog(), "Layout size doesn't match bounds size. Requesting layout from above.");
353366
// The layout that we have specifies that this node (self) would like to be a different size
354367
// than it currently is. Because that size has been computed within the constrainedSize, we
355368
// expect that calling setNeedsLayoutFromAbove will result in our parent resizing us to this.
@@ -506,10 +519,13 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
506519
measurementCompletion:(void(^)())completion
507520
{
508521
ASDisplayNodeAssertMainThread();
522+
as_activity_create_for_scope("Transition node layout");
523+
as_log_debug(ASLayoutLog(), "Transition layout for %@ sizeRange %@ anim %d asyncMeasure %d", self, NSStringFromASSizeRange(constrainedSize), animated, shouldMeasureAsync);
509524

510525
if (constrainedSize.max.width <= 0.0 || constrainedSize.max.height <= 0.0) {
511526
// Using CGSizeZero for the sizeRange can cause negative values in client layout code.
512527
// Most likely called transitionLayout: without providing a size, before first layout pass.
528+
as_log_verbose(ASLayoutLog(), "Ignoring transition due to bad size range.");
513529
return;
514530
}
515531

@@ -526,9 +542,14 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
526542

527543
// Every new layout transition has a transition id associated to check in subsequent transitions for cancelling
528544
int32_t transitionID = [self _startNewTransition];
545+
as_log_verbose(ASLayoutLog(), "Transition ID is %d", transitionID);
529546
// NOTE: This block captures self. It's cheaper than hitting the weak table.
530547
asdisplaynode_iscancelled_block_t isCancelled = ^{
531-
return (BOOL)(_transitionID != transitionID);
548+
BOOL result = (_transitionID != transitionID);
549+
if (result) {
550+
as_log_verbose(ASLayoutLog(), "Transition %d canceled, superseded by %d", transitionID, _transitionID.load());
551+
}
552+
return result;
532553
};
533554

534555
// Move all subnodes in layout pending state for this transition
@@ -573,6 +594,7 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
573594
if (isCancelled()) {
574595
return;
575596
}
597+
as_activity_create_for_scope("Commit layout transition");
576598
ASLayoutTransition *pendingLayoutTransition;
577599
_ASTransitionContext *pendingLayoutTransitionContext;
578600
{
@@ -598,10 +620,13 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
598620
}
599621

600622
// Apply complete layout transitions for all subnodes
601-
ASDisplayNodePerformBlockOnEverySubnode(self, NO, ^(ASDisplayNode * _Nonnull node) {
602-
[node _completePendingLayoutTransition];
603-
node.hierarchyState &= (~ASHierarchyStateLayoutPending);
604-
});
623+
{
624+
as_activity_create_for_scope("Complete pending layout transitions for subtree");
625+
ASDisplayNodePerformBlockOnEverySubnode(self, NO, ^(ASDisplayNode * _Nonnull node) {
626+
[node _completePendingLayoutTransition];
627+
node.hierarchyState &= (~ASHierarchyStateLayoutPending);
628+
});
629+
}
605630

606631
// Measurement pass completion
607632
// Give the subclass a change to hook into before calling the completion block
@@ -614,7 +639,10 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
614639
[pendingLayoutTransition applySubnodeInsertions];
615640

616641
// Kick off animating the layout transition
617-
[self animateLayoutTransition:pendingLayoutTransitionContext];
642+
{
643+
as_activity_create_for_scope("Animate layout transition");
644+
[self animateLayoutTransition:pendingLayoutTransitionContext];
645+
}
618646

619647
// Mark transaction as finished
620648
[self _finishOrCancelTransition];
@@ -805,7 +833,7 @@ - (void)_completePendingLayoutTransition
805833
*/
806834
- (void)_completeLayoutTransition:(ASLayoutTransition *)layoutTransition
807835
{
808-
// Layout transition is not supported for nodes that are not have automatic subnode management enabled
836+
// Layout transition is not supported for nodes that do not have automatic subnode management enabled
809837
if (layoutTransition == nil || self.automaticallyManagesSubnodes == NO) {
810838
return;
811839
}

Source/ASDisplayNode+Subclasses.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ NS_ASSUME_NONNULL_BEGIN
514514

515515
@end
516516

517-
#define ASDisplayNodeAssertThreadAffinity(viewNode) ASDisplayNodeAssert(!viewNode || ASDisplayNodeThreadIsMain() || !(viewNode).nodeLoaded, @"Incorrect display node thread affinity - this method should not be called off the main thread after the ASDisplayNode's view or layer have been created")
518-
#define ASDisplayNodeCAssertThreadAffinity(viewNode) ASDisplayNodeCAssert(!viewNode || ASDisplayNodeThreadIsMain() || !(viewNode).nodeLoaded, @"Incorrect display node thread affinity - this method should not be called off the main thread after the ASDisplayNode's view or layer have been created")
517+
#define ASDisplayNodeAssertThreadAffinity(viewNode) ASDisplayNodeAssert(!viewNode || ASMainThreadAssertionsAreDisabled() || ASDisplayNodeThreadIsMain() || !(viewNode).nodeLoaded, @"Incorrect display node thread affinity - this method should not be called off the main thread after the ASDisplayNode's view or layer have been created")
518+
#define ASDisplayNodeCAssertThreadAffinity(viewNode) ASDisplayNodeCAssert(!viewNode || ASMainThreadAssertionsAreDisabled() || ASDisplayNodeThreadIsMain() || !(viewNode).nodeLoaded, @"Incorrect display node thread affinity - this method should not be called off the main thread after the ASDisplayNode's view or layer have been created")
519519

520520
NS_ASSUME_NONNULL_END

Source/ASDisplayNode.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,9 +748,6 @@ extern NSInteger const ASDefaultDrawingPriority;
748748

749749
@end
750750

751-
@interface ASDisplayNode (ASLayoutElementAsciiArtProtocol) <ASLayoutElementAsciiArtProtocol>
752-
@end
753-
754751
@interface ASDisplayNode (ASLayout)
755752

756753
/** @name Managing dimensions */

0 commit comments

Comments
 (0)