[ASDisplayNode] Majorly Improve Descriptions (#2208)

* Up our description game big time

* Couple tweaks

* Explain logic

* Fix indentation
This commit is contained in:
Adlai Holler 2016-09-07 20:11:27 -07:00 committed by GitHub
parent 0aeefaf25f
commit 5593bfa4d1
11 changed files with 341 additions and 58 deletions

View File

@ -199,13 +199,13 @@
68FC85EA1CE29C7D00EDD713 /* ASVisibilityProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
68FC85EB1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */; };
68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */; };
6959433E1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
695943401D70815300B0EE1F /* ASDisplayNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */; };
696FCB311D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */; };
69708BA61D76386D005C3CF9 /* ASEqualityHashHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 69708BA41D76386D005C3CF9 /* ASEqualityHashHelpers.h */; };
69708BA71D76386D005C3CF9 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */; };
69708BA81D76386D005C3CF9 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */; };
6959433E1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
695943401D70815300B0EE1F /* ASDisplayNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */; };
697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */; };
697C0DE41CF38F28001DE0D4 /* ASLayoutValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */; };
697C0DE51CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */; };
@ -423,6 +423,9 @@
CC3B208C1C3F7A5400798563 /* ASWeakSet.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3B20881C3F7A5400798563 /* ASWeakSet.m */; };
CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */; };
CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; };
CC446A2F1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC446A2D1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h */; };
CC446A301D80AAE00071FD03 /* ASObjectDescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC446A2E1D80AAE00071FD03 /* ASObjectDescriptionHelpers.m */; };
CC446A311D80AAE00071FD03 /* ASObjectDescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC446A2E1D80AAE00071FD03 /* ASObjectDescriptionHelpers.m */; };
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */; };
CC4981BD1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */; };
CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = CC54A81B1D70077A00296A24 /* ASDispatch.h */; };
@ -430,6 +433,7 @@
CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; };
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; };
CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
CC88F7AE1D80AF5E000D6D4E /* ASObjectDescriptionHelpers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CC446A2D1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h */; };
CC8B05D61D73836400F54286 /* ASPerformanceTestContext.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D51D73836400F54286 /* ASPerformanceTestContext.m */; };
CC8B05D81D73979700F54286 /* ASTextNodePerformanceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */; };
CCA221D31D6FA7EF00AF6A0F /* ASViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */; };
@ -642,6 +646,7 @@
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
CC88F7AE1D80AF5E000D6D4E /* ASObjectDescriptionHelpers.h in CopyFiles */,
F7CE6C981D2CDB5800BE4C15 /* ASInternalHelpers.h in CopyFiles */,
F7CE6CB71D2CE2D000BE4C15 /* ASLayoutableExtensibility.h in CopyFiles */,
F7CE6C131D2CDB3E00BE4C15 /* ASPagerFlowLayout.h in CopyFiles */,
@ -969,11 +974,11 @@
68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTabBarController.m; sourceTree = "<group>"; };
68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVisibilityProtocols.h; sourceTree = "<group>"; };
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVisibilityProtocols.m; sourceTree = "<group>"; };
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayout.mm; sourceTree = "<group>"; };
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeLayout.h; sourceTree = "<group>"; };
696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBackgroundLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
69708BA41D76386D005C3CF9 /* ASEqualityHashHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASEqualityHashHelpers.h; path = TextKit/ASEqualityHashHelpers.h; sourceTree = "<group>"; };
69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASEqualityHashHelpers.mm; path = TextKit/ASEqualityHashHelpers.mm; sourceTree = "<group>"; };
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayout.mm; sourceTree = "<group>"; };
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeLayout.h; sourceTree = "<group>"; };
697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEditableTextNodeTests.m; sourceTree = "<group>"; };
697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutValidation.h; path = AsyncDisplayKit/Layout/ASLayoutValidation.h; sourceTree = "<group>"; };
697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutValidation.mm; path = AsyncDisplayKit/Layout/ASLayoutValidation.mm; sourceTree = "<group>"; };
@ -1101,6 +1106,8 @@
CC3B20881C3F7A5400798563 /* ASWeakSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakSet.m; sourceTree = "<group>"; };
CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakSetTests.m; sourceTree = "<group>"; };
CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBridgedPropertiesTests.mm; sourceTree = "<group>"; };
CC446A2D1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASObjectDescriptionHelpers.h; sourceTree = "<group>"; };
CC446A2E1D80AAE00071FD03 /* ASObjectDescriptionHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASObjectDescriptionHelpers.m; sourceTree = "<group>"; };
CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewThrashTests.m; sourceTree = "<group>"; };
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+ASHelpers.h"; sourceTree = "<group>"; };
CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+ASHelpers.m"; sourceTree = "<group>"; };
@ -1508,6 +1515,8 @@
058D0A01195D050800B7D73C /* Private */ = {
isa = PBXGroup;
children = (
CC446A2D1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h */,
CC446A2E1D80AAE00071FD03 /* ASObjectDescriptionHelpers.m */,
CC54A81B1D70077A00296A24 /* ASDispatch.h */,
058D0A02195D050800B7D73C /* _AS-objc-internal.h */,
058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */,
@ -1864,6 +1873,7 @@
34EFC7771B701D2D00AD841F /* ASStackUnpositionedLayout.h in Headers */,
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */,
34EFC7731B701D0700AD841F /* ASStaticLayoutSpec.h in Headers */,
CC446A2F1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h in Headers */,
254C6B781BF94DF4003EC431 /* ASTextKitContext.h in Headers */,
B350620A1B010EFD0018CF92 /* ASTableView.h in Headers */,
B350620C1B010EFD0018CF92 /* ASTableViewProtocols.h in Headers */,
@ -2152,6 +2162,7 @@
CC4981BD1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m in Sources */,
DB55C2631C6408D6004EDCF5 /* _ASTransitionContext.m in Sources */,
92074A631CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */,
CC446A301D80AAE00071FD03 /* ASObjectDescriptionHelpers.m in Sources */,
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */,
ACF6ED271B17843500DA7C62 /* ASLayoutSpec.mm in Sources */,
257754B01BEE44CD00737CA5 /* ASTextKitRenderer+TextChecking.mm in Sources */,
@ -2333,6 +2344,7 @@
9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.m in Sources */,
92074A641CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */,
B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */,
CC446A311D80AAE00071FD03 /* ASObjectDescriptionHelpers.m in Sources */,
68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */,
B35062031B010EFD0018CF92 /* ASImageNode.mm in Sources */,
254C6B821BF94F8A003EC431 /* ASTextKitComponents.m in Sources */,

View File

@ -12,10 +12,13 @@
#import "ASEqualityHelpers.h"
#import "ASDisplayNodeInternal.h"
#import "ASDisplayNode+FrameworkPrivate.h"
#import <AsyncDisplayKit/_ASDisplayView.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNode+Beta.h>
#import <AsyncDisplayKit/ASTextNode.h>
#import <AsyncDisplayKit/ASCollectionNode.h>
#import <AsyncDisplayKit/ASTableNode.h>
#import <AsyncDisplayKit/ASViewController.h>
#import <AsyncDisplayKit/ASInsetLayoutSpec.h>
@ -276,6 +279,35 @@
withCellFrame:cellFrame];
}
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
{
NSMutableArray *result = [super propertiesForDebugDescription];
UIScrollView *scrollView = self.scrollView;
ASDisplayNode *owningNode = scrollView.asyncdisplaykit_node;
if ([owningNode isKindOfClass:[ASCollectionNode class]]) {
[result addObject:@{ @"collectionNode" : ASObjectDescriptionMakeTiny(owningNode) }];
} else if ([owningNode isKindOfClass:[ASTableNode class]]) {
[result addObject:@{ @"tableNode" : ASObjectDescriptionMakeTiny(owningNode) }];
} else if ([scrollView isKindOfClass:[ASCollectionView class]]) {
NSIndexPath *ip = [(ASCollectionView *)scrollView indexPathForNode:self];
if (ip != nil) {
[result addObject:@{ @"indexPath" : ip }];
}
[result addObject:@{ @"collectionView" : ASObjectDescriptionMakeTiny(scrollView) }];
} else if ([scrollView isKindOfClass:[ASTableView class]]) {
NSIndexPath *ip = [(ASTableView *)scrollView indexPathForNode:self];
if (ip != nil) {
[result addObject:@{ @"indexPath" : ip }];
}
[result addObject:@{ @"tableView" : ASObjectDescriptionMakeTiny(scrollView) }];
}
return result;
}
@end

View File

@ -32,7 +32,7 @@
#import "ASLayout.h"
#import "ASLayoutSpec.h"
#import "ASLayoutValidation.h"
#import "ASCellNode.h"
#import "ASCellNode+Internal.h"
NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority;
NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification = @"ASRenderingEngineDidDisplayScheduledNodes";
@ -3144,6 +3144,93 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
return self;
}
#pragma mark Debugging (Private)
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
{
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
if (self.name.length > 0) {
[result addObject:@{ @"name" : ASStringWithQuotesIfMultiword(self.name) }];
}
return result;
}
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
{
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
if (self.name.length > 0) {
[result addObject:@{ @"name" : ASStringWithQuotesIfMultiword(self.name)}];
}
CGRect windowFrame = [self _frameInWindow];
if (CGRectIsNull(windowFrame) == NO) {
[result addObject:@{ @"frameInWindow" : [NSValue valueWithCGRect:windowFrame] }];
}
if (_view != nil) {
[result addObject:@{ @"frame" : [NSValue valueWithCGRect:_view.frame] }];
} else if (_layer != nil) {
[result addObject:@{ @"frame" : [NSValue valueWithCGRect:_layer.frame] }];
} else {
[result addObject:@{ @"frame" : [NSValue valueWithCGRect:self.frame] }];
}
// Check supernode so that if we are cell node we don't find self.
ASCellNode *cellNode = ASDisplayNodeFindFirstSupernodeOfClass(self.supernode, [ASCellNode class]);
if (cellNode != nil) {
[result addObject:@{ @"cellNode" : ASObjectDescriptionMakeTiny(cellNode) }];
}
[result addObject:@{ @"interfaceState" : NSStringFromASInterfaceState(self.interfaceState)} ];
if (_view != nil) {
[result addObject:@{ @"view" : ASObjectDescriptionMakeTiny(_view) }];
} else if (_layer != nil) {
[result addObject:@{ @"layer" : ASObjectDescriptionMakeTiny(_layer) }];
} else if (_viewClass != nil) {
[result addObject:@{ @"viewClass" : _viewClass }];
} else if (_layerClass != nil) {
[result addObject:@{ @"layerClass" : _layerClass }];
} else if (_viewBlock != nil) {
[result addObject:@{ @"viewBlock" : _viewBlock }];
} else if (_layerBlock != nil) {
[result addObject:@{ @"layerBlock" : _layerBlock }];
}
return result;
}
- (NSString *)description
{
return ASObjectDescriptionMake(self, [self propertiesForDescription]);
}
- (NSString *)debugDescription
{
return ASObjectDescriptionMake(self, [self propertiesForDebugDescription]);
}
// This should only be called for debugging. It's not thread safe and it doesn't assert.
// NOTE: Returns CGRectNull if the node isn't in a hierarchy.
- (CGRect)_frameInWindow
{
if (self.isNodeLoaded == NO || self.isInHierarchy == NO) {
return CGRectNull;
}
if (self.layerBacked) {
CALayer *rootLayer = self.layer;
CALayer *nextLayer = rootLayer;
while ((nextLayer = rootLayer.superlayer) != nil) {
rootLayer = nextLayer;
}
return [self.layer convertRect:self.threadSafeBounds toLayer:rootLayer];
} else {
return [self.view convertRect:self.threadSafeBounds toView:nil];
}
}
#pragma mark - ASEnvironment
@ -3258,38 +3345,6 @@ ASEnvironmentLayoutExtensibilityForwarding
@implementation ASDisplayNode (Debugging)
- (NSString *)description
{
if (self.name) {
return [NSString stringWithFormat:@"<%@ %p name = %@>", self.class, self, self.name];
} else {
return [super description];
}
}
- (NSString *)debugDescription
{
NSString *notableTargetDesc = (_flags.layerBacked ? @" [layer]" : @" [view]");
if (_view && _viewClass) { // Nonstandard view is loaded
notableTargetDesc = [NSString stringWithFormat:@" [%@ : %p]", _view.class, _view];
} else if (_layer && _layerClass) { // Nonstandard layer is loaded
notableTargetDesc = [NSString stringWithFormat:@" [%@ : %p]", _layer.class, _layer];
} else if (_viewClass) { // Nonstandard view class unloaded
notableTargetDesc = [NSString stringWithFormat:@" [%@]", _viewClass];
} else if (_layerClass) { // Nonstandard layer class unloaded
notableTargetDesc = [NSString stringWithFormat:@" [%@]", _layerClass];
} else if (_viewBlock) { // Nonstandard lazy view unloaded
notableTargetDesc = @" [block]";
} else if (_layerBlock) { // Nonstandard lazy layer unloaded
notableTargetDesc = @" [block]";
}
if (self.name) {
return [NSString stringWithFormat:@"<%@ %p name = %@%@>", self.class, self, self.name, notableTargetDesc];
} else {
return [NSString stringWithFormat:@"<%@ %p%@>", self.class, self, notableTargetDesc];
}
}
- (NSString *)descriptionForRecursiveDescription
{
NSString *creationTypeString = nil;

View File

@ -46,13 +46,13 @@ ASDISPLAYNODE_INLINE NSString * _Nonnull NSStringFromASInterfaceState(ASInterfac
[states addObject:@"MeasureLayout"];
}
if (ASInterfaceStateIncludesPreload(interfaceState)) {
[states addObject:@" | Preload"];
[states addObject:@"Preload"];
}
if (ASInterfaceStateIncludesDisplay(interfaceState)) {
[states addObject:@" | Display"];
[states addObject:@"Display"];
}
if (ASInterfaceStateIncludesVisible(interfaceState)) {
[states addObject:@" | Visible"];
[states addObject:@"Visible"];
}
return [NSString stringWithFormat:@"{ %@ }", [states componentsJoinedByString:@" | "]];
}

View File

@ -28,6 +28,7 @@
#import "ASLayout.h"
#import "CGRect+ASConvenience.h"
#import "ASObjectDescriptionHelpers.h"
/**
* If set, we will record all values set to attributedText into an array
@ -222,15 +223,35 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
}
}
- (NSString *)description
#pragma mark - Description
- (NSString *)_plainStringForDescription
{
ASDN::MutexLocker l(__instanceLock__);
NSString *plainString = [[_attributedText string] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSString *truncationString = [_composedTruncationText string];
if (plainString.length > 50)
NSString *plainString = [[self.attributedText string] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
if (plainString.length > 50) {
plainString = [[plainString substringToIndex:50] stringByAppendingString:@"\u2026"];
return [NSString stringWithFormat:@"<%@: %p; text = \"%@\"; truncation string = \"%@\"; frame = %@; renderer = %p>", self.class, self, plainString, truncationString, self.nodeLoaded ? NSStringFromCGRect(self.layer.frame) : nil, [self _renderer]];
}
return plainString;
}
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
{
NSMutableArray *result = [super propertiesForDescription];
NSString *plainString = [self _plainStringForDescription];
if (plainString.length > 0) {
[result insertObject:@{ @"text" : ASStringWithQuotesIfMultiword(plainString) } atIndex:0];
}
return result;
}
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
{
NSMutableArray *result = [super propertiesForDebugDescription];
NSString *plainString = [self _plainStringForDescription];
if (plainString.length > 0) {
[result insertObject:@{ @"text" : ASStringWithQuotesIfMultiword(plainString) } atIndex:0];
}
return result;
}
#pragma mark - ASDisplayNode

View File

@ -17,6 +17,7 @@
#import "ASDisplayNode.h"
#import "ASDisplayNodeInternal.h"
#import "ASDisplayNode+FrameworkPrivate.h"
#import "ASObjectDescriptionHelpers.h"
@implementation _ASDisplayLayer
{
@ -236,11 +237,21 @@
[strongAsyncDelegate cancelDisplayAsyncLayer:self];
}
// e.g. <MYTextNodeLayer: 0xFFFFFF; node = <MYTextNode: 0xFFFFFFE; name = "Username node for user 179">>
- (NSString *)description
{
// The standard UIView description is useless for debugging because all ASDisplayNode subclasses have _ASDisplayView-type views.
// This allows us to at least see the name of the node subclass and get its pointer directly from [[UIWindow keyWindow] recursiveDescription].
return [NSString stringWithFormat:@"<%@, layer = %@>", self.asyncdisplaykit_node, [super description]];
NSMutableString *description = [[super description] mutableCopy];
ASDisplayNode *node = self.asyncdisplaykit_node;
if (node != nil) {
NSString *classString = [NSString stringWithFormat:@"%@-", [node class]];
[description replaceOccurrencesOfString:@"_ASDisplay" withString:classString options:kNilOptions range:NSMakeRange(0, description.length)];
NSUInteger insertionIndex = [description rangeOfString:@">"].location;
if (insertionIndex != NSNotFound) {
NSString *nodeString = [NSString stringWithFormat:@"; node = %@", node];
[description insertString:nodeString atIndex:insertionIndex];
}
}
return description;
}
@end

View File

@ -15,6 +15,7 @@
#import "ASDisplayNodeInternal.h"
#import "ASDisplayNode+FrameworkPrivate.h"
#import "ASDisplayNode+Subclasses.h"
#import "ASObjectDescriptionHelpers.h"
@interface _ASDisplayView ()
@property (nonatomic, assign, readwrite) ASDisplayNode *asyncdisplaykit_node;
@ -44,11 +45,32 @@
#pragma mark - NSObject Overrides
// e.g. <MYPhotoNodeView: 0xFFFFFF; node = <MYPhotoNode: 0xFFFFFE>; frame = ...>
- (NSString *)description
{
// The standard UIView description is useless for debugging because all ASDisplayNode subclasses have _ASDisplayView-type views.
// This allows us to at least see the name of the node subclass and get its pointer directly from [[UIWindow keyWindow] recursiveDescription].
return [NSString stringWithFormat:@"<%@, view = %@>", _node, [super description]];
NSMutableString *description = [[super description] mutableCopy];
ASDisplayNode *node = _node;
if (node != nil) {
NSString *classString = [NSString stringWithFormat:@"%@-", [node class]];
[description replaceOccurrencesOfString:@"_ASDisplay" withString:classString options:kNilOptions range:NSMakeRange(0, description.length)];
NSUInteger semicolon = [description rangeOfString:@";"].location;
if (semicolon != NSNotFound) {
NSString *nodeString = [NSString stringWithFormat:@"; node = %@", node];
[description insertString:nodeString atIndex:semicolon];
}
// Remove layer description it never contains valuable info and it duplicates the node info. Noisy.
NSRange layerDescriptionRange = [description rangeOfString:@"; layer = <.*>" options:NSRegularExpressionSearch];
if (layerDescriptionRange.location != NSNotFound) {
[description replaceCharactersInRange:layerDescriptionRange withString:@""];
// Our regex will grab the closing angle bracket and I'm not clever enough to come up with a better one, so re-add it if needed.
if ([description hasSuffix:@">"] == NO) {
[description appendString:@">"];
}
}
}
return description;
}
#pragma mark - UIView Overrides

View File

@ -15,6 +15,7 @@
#import "ASLayoutSpecUtilities.h"
#import <queue>
#import "ASObjectDescriptionHelpers.h"
CGPoint const CGPointNull = {NAN, NAN};
@ -38,7 +39,7 @@ static inline NSString * descriptionIndents(NSUInteger indents)
return description;
}
@interface ASLayout ()
@interface ASLayout () <ASDescriptionProvider>
/**
* A boolean describing if the current layout has been flattened.
@ -205,10 +206,18 @@ static inline NSString * descriptionIndents(NSUInteger indents)
#pragma mark - Description
- (NSMutableArray <NSDictionary *> *)propertiesForDescription
{
NSMutableArray *result = [NSMutableArray array];
[result addObject:@{ @"layoutable" : (self.layoutable ?: (id)kCFNull) }];
[result addObject:@{ @"position" : [NSValue valueWithCGPoint:self.position] }];
[result addObject:@{ @"size" : [NSValue valueWithCGSize:self.size] }];
return result;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<<ASLayout: %p>, layoutable = %@, position = %@; size = %@;>",
self, self.layoutable, NSStringFromCGPoint(self.position), NSStringFromCGSize(self.size)/*, NSStringFromASSizeRange(self.constrainedSize)*/];
return ASObjectDescriptionMake(self, [self propertiesForDescription]);
}
- (NSString *)recursiveDescription

View File

@ -20,6 +20,7 @@
#import "_ASTransitionContext.h"
#import "ASLayoutTransition.h"
#import "ASEnvironment.h"
#import "ASObjectDescriptionHelpers.h"
@protocol _ASDisplayLayerDelegate;
@class _ASDisplayLayer;
@ -51,7 +52,7 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
#define TIME_DISPLAYNODE_OPS 0 // If you're using this information frequently, try: (DEBUG || PROFILE)
@interface ASDisplayNode ()
@interface ASDisplayNode () <ASDescriptionProvider, ASDebugDescriptionProvider>
{
@package
_ASPendingState *_pendingViewState;

View File

@ -0,0 +1,49 @@
//
// ASObjectDescriptions.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 9/7/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <CoreGraphics/CoreGraphics.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Your base class should conform to this and override `-debugDescription`
* to call `[self propertiesForDebugDescription]` and use `ASObjectDescriptionMake`
* to return a string. Subclasses of this base class just need to override
* `propertiesForDebugDescription`, call super, and modify the result as needed.
*/
@protocol ASDebugDescriptionProvider
@required
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription;
@end
/**
* Your base class should conform to this and override `-description`
* to call `[self propertiesForDescription]` and use `ASObjectDescriptionMake`
* to return a string. Subclasses of this base class just need to override
* `propertiesForDescription`, call super, and modify the result as needed.
*/
@protocol ASDescriptionProvider
@required
- (NSMutableArray<NSDictionary *> *)propertiesForDescription;
@end
ASDISPLAYNODE_EXTERN_C_BEGIN
/// Returns e.g. <MYObject: 0xFFFFFFFF; name = "Object Name"; frame = (0 0; 50 50)>
NSString *ASObjectDescriptionMake(id object, NSArray<NSDictionary *> * _Nullable propertyGroups);
/// Returns e.g. <MYObject: 0xFFFFFFFF>
NSString *ASObjectDescriptionMakeTiny(id object);
NSString * _Nullable ASStringWithQuotesIfMultiword(NSString * _Nullable string);
ASDISPLAYNODE_EXTERN_C_END
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,71 @@
//
// ASObjectDescriptions.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 9/7/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import "ASObjectDescriptionHelpers.h"
#import <UIKit/UIKit.h>
#import "NSIndexSet+ASHelpers.h"
NSString *ASGetDescriptionValueString(id object) {
if ([object isKindOfClass:[NSValue class]]) {
// Use shortened NSValue descriptions
NSValue *value = object;
const char *type = value.objCType;
if (strcmp(type, @encode(CGRect)) == 0) {
CGRect rect = [value CGRectValue];
return [NSString stringWithFormat:@"(%g %g; %g %g)", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height];
} else if (strcmp(type, @encode(CGSize)) == 0) {
return NSStringFromCGSize(value.CGSizeValue);
} else if (strcmp(type, @encode(CGPoint)) == 0) {
return NSStringFromCGPoint(value.CGPointValue);
}
} else if ([object isKindOfClass:[NSIndexSet class]]) {
return [object as_smallDescription];
} else if ([object isKindOfClass:[NSIndexPath class]]) {
// index paths like (0, 7)
NSIndexPath *indexPath = object;
NSMutableArray *strings = [NSMutableArray array];
for (NSUInteger i = 0; i < indexPath.length; i++) {
[strings addObject:[NSString stringWithFormat:@"%lu", (unsigned long)[indexPath indexAtPosition:i]]];
}
return [NSString stringWithFormat:@"(%@)", [strings componentsJoinedByString:@", "]];
}
return [object description];
}
NSString *ASObjectDescriptionMake(id object, NSArray<NSDictionary *> *propertyGroups) {
NSMutableString *str = [NSMutableString stringWithFormat:@"<%@: %p", [object class], object];
NSMutableArray *components = [NSMutableArray array];
for (NSDictionary *properties in propertyGroups) {
[properties enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
[components addObject:[NSString stringWithFormat:@"%@ = %@", key, ASGetDescriptionValueString(obj)]];
}];
}
if (components.count > 0) {
[str appendString:@"; "];
[str appendString:[components componentsJoinedByString:@"; "]];
}
[str appendString:@">"];
return str;
}
NSString *ASObjectDescriptionMakeTiny(id object) {
return ASObjectDescriptionMake(object, nil);
}
NSString *ASStringWithQuotesIfMultiword(NSString *string) {
if (string == nil) {
return nil;
}
if ([string rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]].location != NSNotFound) {
return [NSString stringWithFormat:@"\"%@\"", string];
} else {
return string;
}
}