mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-05 20:22:15 +00:00
Beter table/collection update history (#2562)
- Introduce thread-safe ASEventLog - ASCollectionNode and ASTableNode share their event log with their ASDataController. The controller uses it to log change set submitting and finishing events. - ASCollectionNode and ASTableNode print their data source and delegate in their debug description.
This commit is contained in:
parent
06f5754b37
commit
fb6d1830a0
@ -486,6 +486,10 @@
|
|||||||
E52405B31C8FEF03004DC8E7 /* ASLayoutTransition.mm in Sources */ = {isa = PBXBuildFile; fileRef = E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */; };
|
E52405B31C8FEF03004DC8E7 /* ASLayoutTransition.mm in Sources */ = {isa = PBXBuildFile; fileRef = E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */; };
|
||||||
E55D86321CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; };
|
E55D86321CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; };
|
||||||
E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; };
|
E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; };
|
||||||
|
E55FFC8F1DCCA50700060AC4 /* ASEventLog.h in Headers */ = {isa = PBXBuildFile; fileRef = E55FFC8E1DCCA50700060AC4 /* ASEventLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
E55FFC911DCCA5A600060AC4 /* ASEventLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55FFC901DCCA5A600060AC4 /* ASEventLog.mm */; };
|
||||||
|
E55FFC921DCCA5A600060AC4 /* ASEventLog.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55FFC901DCCA5A600060AC4 /* ASEventLog.mm */; };
|
||||||
|
E55FFC931DCCB0A800060AC4 /* ASEventLog.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = E55FFC8E1DCCA50700060AC4 /* ASEventLog.h */; };
|
||||||
E5711A2C1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */; };
|
E5711A2C1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */; };
|
||||||
E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */; };
|
E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */; };
|
||||||
E5711A301C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */; };
|
E5711A301C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */; };
|
||||||
@ -658,6 +662,7 @@
|
|||||||
dstPath = "include/$(PRODUCT_NAME)";
|
dstPath = "include/$(PRODUCT_NAME)";
|
||||||
dstSubfolderSpec = 16;
|
dstSubfolderSpec = 16;
|
||||||
files = (
|
files = (
|
||||||
|
E55FFC931DCCB0A800060AC4 /* ASEventLog.h in CopyFiles */,
|
||||||
693117CE1DC7C72700DE4784 /* ASDisplayNode+Deprecated.h in CopyFiles */,
|
693117CE1DC7C72700DE4784 /* ASDisplayNode+Deprecated.h in CopyFiles */,
|
||||||
69F381A51DA4630D00CF2278 /* NSArray+Diffing.h in CopyFiles */,
|
69F381A51DA4630D00CF2278 /* NSArray+Diffing.h in CopyFiles */,
|
||||||
CC4C2A7A1D8902350039ACAB /* ASTraceEvent.h in CopyFiles */,
|
CC4C2A7A1D8902350039ACAB /* ASTraceEvent.h in CopyFiles */,
|
||||||
@ -1168,6 +1173,8 @@
|
|||||||
E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTransition.mm; sourceTree = "<group>"; };
|
E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTransition.mm; sourceTree = "<group>"; };
|
||||||
E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = "<group>"; };
|
E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = "<group>"; };
|
||||||
E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutElement.mm; path = AsyncDisplayKit/Layout/ASLayoutElement.mm; sourceTree = "<group>"; };
|
E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutElement.mm; path = AsyncDisplayKit/Layout/ASLayoutElement.mm; sourceTree = "<group>"; };
|
||||||
|
E55FFC8E1DCCA50700060AC4 /* ASEventLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEventLog.h; sourceTree = "<group>"; };
|
||||||
|
E55FFC901DCCA5A600060AC4 /* ASEventLog.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEventLog.mm; sourceTree = "<group>"; };
|
||||||
E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIndexedNodeContext.h; sourceTree = "<group>"; };
|
E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIndexedNodeContext.h; sourceTree = "<group>"; };
|
||||||
E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIndexedNodeContext.mm; sourceTree = "<group>"; };
|
E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIndexedNodeContext.mm; sourceTree = "<group>"; };
|
||||||
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@ -1583,6 +1590,8 @@
|
|||||||
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */,
|
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */,
|
||||||
69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */,
|
69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */,
|
||||||
69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */,
|
69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */,
|
||||||
|
E55FFC8E1DCCA50700060AC4 /* ASEventLog.h */,
|
||||||
|
E55FFC901DCCA5A600060AC4 /* ASEventLog.mm */,
|
||||||
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */,
|
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */,
|
||||||
058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */,
|
058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */,
|
||||||
058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */,
|
058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */,
|
||||||
@ -1765,6 +1774,7 @@
|
|||||||
isa = PBXHeadersBuildPhase;
|
isa = PBXHeadersBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
E55FFC8F1DCCA50700060AC4 /* ASEventLog.h in Headers */,
|
||||||
683489281D70DE3400327501 /* ASDisplayNode+Deprecated.h in Headers */,
|
683489281D70DE3400327501 /* ASDisplayNode+Deprecated.h in Headers */,
|
||||||
6907C2581DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h in Headers */,
|
6907C2581DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h in Headers */,
|
||||||
69E0E8A71D356C9400627613 /* ASEqualityHelpers.h in Headers */,
|
69E0E8A71D356C9400627613 /* ASEqualityHelpers.h in Headers */,
|
||||||
@ -2235,6 +2245,7 @@
|
|||||||
E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */,
|
E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */,
|
||||||
9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
||||||
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */,
|
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */,
|
||||||
|
E55FFC911DCCA5A600060AC4 /* ASEventLog.mm in Sources */,
|
||||||
ACF6ED301B17843500DA7C62 /* ASStackLayoutSpec.mm in Sources */,
|
ACF6ED301B17843500DA7C62 /* ASStackLayoutSpec.mm in Sources */,
|
||||||
257754BE1BEE458E00737CA5 /* ASTextKitComponents.m in Sources */,
|
257754BE1BEE458E00737CA5 /* ASTextKitComponents.m in Sources */,
|
||||||
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
|
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
|
||||||
@ -2422,6 +2433,7 @@
|
|||||||
254C6B851BF94F8A003EC431 /* ASTextKitAttributes.mm in Sources */,
|
254C6B851BF94F8A003EC431 /* ASTextKitAttributes.mm in Sources */,
|
||||||
509E68601B3AED8E009B9150 /* ASScrollDirection.m in Sources */,
|
509E68601B3AED8E009B9150 /* ASScrollDirection.m in Sources */,
|
||||||
B35062091B010EFD0018CF92 /* ASScrollNode.m in Sources */,
|
B35062091B010EFD0018CF92 /* ASScrollNode.m in Sources */,
|
||||||
|
E55FFC921DCCA5A600060AC4 /* ASEventLog.mm in Sources */,
|
||||||
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
||||||
8BDA5FC81CDBDF95007D13B2 /* ASVideoPlayerNode.mm in Sources */,
|
8BDA5FC81CDBDF95007D13B2 /* ASVideoPlayerNode.mm in Sources */,
|
||||||
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#import "ASCollectionInternal.h"
|
#import "ASCollectionInternal.h"
|
||||||
#import "ASCollectionViewLayoutFacilitatorProtocol.h"
|
#import "ASCollectionViewLayoutFacilitatorProtocol.h"
|
||||||
#import "ASCollectionNode.h"
|
#import "ASCollectionNode.h"
|
||||||
|
#import "ASDisplayNodeInternal.h"
|
||||||
#import "ASDisplayNode+Subclasses.h"
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
#import "ASEnvironmentInternal.h"
|
#import "ASEnvironmentInternal.h"
|
||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
@ -121,7 +122,7 @@
|
|||||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator
|
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator
|
||||||
{
|
{
|
||||||
ASDisplayNodeViewBlock collectionViewBlock = ^UIView *{
|
ASDisplayNodeViewBlock collectionViewBlock = ^UIView *{
|
||||||
return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:layoutFacilitator];
|
return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:layoutFacilitator eventLog:ASDisplayNodeGetEventLog(self)];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self = [super initWithViewBlock:collectionViewBlock]) {
|
if (self = [super initWithViewBlock:collectionViewBlock]) {
|
||||||
@ -561,4 +562,14 @@
|
|||||||
|
|
||||||
ASEnvironmentCollectionTableSetEnvironmentState(_environmentStateLock)
|
ASEnvironmentCollectionTableSetEnvironmentState(_environmentStateLock)
|
||||||
|
|
||||||
|
#pragma mark - Debugging (Private)
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [super propertiesForDebugDescription];
|
||||||
|
[result addObject:@{ @"dataSource" : ASObjectDescriptionMakeTiny(self.dataSource) }];
|
||||||
|
[result addObject:@{ @"delegate" : ASObjectDescriptionMakeTiny(self.delegate) }];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -244,10 +244,10 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
|||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
|
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
|
||||||
{
|
{
|
||||||
return [self _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:nil];
|
return [self _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:nil eventLog:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator
|
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator eventLog:(ASEventLog *)eventLog
|
||||||
{
|
{
|
||||||
if (!(self = [super initWithFrame:frame collectionViewLayout:layout]))
|
if (!(self = [super initWithFrame:frame collectionViewLayout:layout]))
|
||||||
return nil;
|
return nil;
|
||||||
@ -259,7 +259,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
|||||||
_rangeController.delegate = self;
|
_rangeController.delegate = self;
|
||||||
_rangeController.layoutController = _layoutController;
|
_rangeController.layoutController = _layoutController;
|
||||||
|
|
||||||
_dataController = [[ASCollectionDataController alloc] initWithDataSource:self];
|
_dataController = [[ASCollectionDataController alloc] initWithDataSource:self eventLog:eventLog];
|
||||||
_dataController.delegate = _rangeController;
|
_dataController.delegate = _rangeController;
|
||||||
_dataController.environmentDelegate = self;
|
_dataController.environmentDelegate = self;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#import "ASDisplayNode.h"
|
#import "ASDisplayNode.h"
|
||||||
#import "ASLayoutRangeType.h"
|
#import "ASLayoutRangeType.h"
|
||||||
#import "ASTraceEvent.h"
|
#import "ASEventLog.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@ -19,20 +19,18 @@ void ASPerformBlockOnMainThread(void (^block)());
|
|||||||
void ASPerformBlockOnBackgroundThread(void (^block)()); // DISPATCH_QUEUE_PRIORITY_DEFAULT
|
void ASPerformBlockOnBackgroundThread(void (^block)()); // DISPATCH_QUEUE_PRIORITY_DEFAULT
|
||||||
ASDISPLAYNODE_EXTERN_C_END
|
ASDISPLAYNODE_EXTERN_C_END
|
||||||
|
|
||||||
#ifndef ASDISPLAYNODE_EVENTLOG_CAPACITY
|
#if ASEVENTLOG_ENABLE
|
||||||
#define ASDISPLAYNODE_EVENTLOG_CAPACITY 20
|
#define ASDisplayNodeLogEvent(node, ...) [node.eventLog logEventWithBacktrace:[NSThread callStackSymbols] format:__VA_ARGS__]
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ASDISPLAYNODE_EVENTLOG_ENABLE
|
|
||||||
#define ASDISPLAYNODE_EVENTLOG_ENABLE DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ASDISPLAYNODE_EVENTLOG_ENABLE
|
|
||||||
#define ASDisplayNodeLogEvent(node, ...) [node _logEventWithBacktrace:[NSThread callStackSymbols] format:__VA_ARGS__]
|
|
||||||
#else
|
#else
|
||||||
#define ASDisplayNodeLogEvent(node, ...)
|
#define ASDisplayNodeLogEvent(node, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
#define ASDisplayNodeGetEventLog(node) node.eventLog
|
||||||
|
#else
|
||||||
|
#define ASDisplayNodeGetEventLog(node) nil
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bitmask to indicate what performance measurements the cell should record.
|
* Bitmask to indicate what performance measurements the cell should record.
|
||||||
*/
|
*/
|
||||||
@ -94,6 +92,13 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
@property (nonatomic, assign, readonly) ASDisplayNodePerformanceMeasurements performanceMeasurements;
|
@property (nonatomic, assign, readonly) ASDisplayNodePerformanceMeasurements performanceMeasurements;
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
/*
|
||||||
|
* @abstract The primitive event tracing object. You shouldn't directly use it to log event. Use the ASDisplayNodeLogEvent macro instead.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, strong, readonly) ASEventLog *eventLog;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Currently used by ASNetworkImageNode and ASMultiplexImageNode to allow their placeholders to stay if they are loading an image from the network.
|
* @abstract Currently used by ASNetworkImageNode and ASMultiplexImageNode to allow their placeholders to stay if they are loading an image from the network.
|
||||||
* Otherwise, a display pass is scheduled and completes, but does not actually draw anything - and ASDisplayNode considers the element finished.
|
* Otherwise, a display pass is scheduled and completes, but does not actually draw anything - and ASDisplayNode considers the element finished.
|
||||||
@ -118,20 +123,6 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
+ (void)setRangeModeForMemoryWarnings:(ASLayoutRangeMode)rangeMode;
|
+ (void)setRangeModeForMemoryWarnings:(ASLayoutRangeMode)rangeMode;
|
||||||
|
|
||||||
#if ASDISPLAYNODE_EVENTLOG_ENABLE
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The primitive event tracing method. You shouldn't call this. Use the ASDisplayNodeLogEvent macro instead.
|
|
||||||
*/
|
|
||||||
- (void)_logEventWithBacktrace:(NSArray<NSString *> *)backtrace format:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract The most recent trace events for this node. Max count is ASDISPLAYNODE_EVENTLOG_CAPACITY.
|
|
||||||
*/
|
|
||||||
@property (readonly, copy) NSArray *eventLog;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -300,7 +300,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
- (void)_initializeInstance
|
- (void)_initializeInstance
|
||||||
{
|
{
|
||||||
[self _staticInitialize];
|
[self _staticInitialize];
|
||||||
_eventLogHead = -1;
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
_eventLog = [[ASEventLog alloc] init];
|
||||||
|
#endif
|
||||||
|
|
||||||
_contentsScaleForDisplay = ASScreenScale();
|
_contentsScaleForDisplay = ASScreenScale();
|
||||||
|
|
||||||
_environmentState = ASEnvironmentStateMakeDefault();
|
_environmentState = ASEnvironmentStateMakeDefault();
|
||||||
@ -575,51 +579,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ASDISPLAYNODE_EVENTLOG_ENABLE
|
|
||||||
- (void)_logEventWithBacktrace:(NSArray<NSString *> *)backtrace format:(NSString *)format, ...
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
ASTraceEvent *event = [[ASTraceEvent alloc] initWithObject:self
|
|
||||||
backtrace:backtrace
|
|
||||||
format:format
|
|
||||||
arguments:args];
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
|
||||||
// Create the array if needed.
|
|
||||||
if (_eventLog == nil) {
|
|
||||||
_eventLog = [NSMutableArray arrayWithCapacity:ASDISPLAYNODE_EVENTLOG_CAPACITY];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment the head index.
|
|
||||||
_eventLogHead = (_eventLogHead + 1) % ASDISPLAYNODE_EVENTLOG_CAPACITY;
|
|
||||||
if (_eventLogHead < _eventLog.count) {
|
|
||||||
[_eventLog replaceObjectAtIndex:_eventLogHead withObject:event];
|
|
||||||
} else {
|
|
||||||
[_eventLog insertObject:event atIndex:_eventLogHead];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray<ASTraceEvent *> *)eventLog
|
|
||||||
{
|
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
|
||||||
NSUInteger tail = (_eventLogHead + 1);
|
|
||||||
NSUInteger count = _eventLog.count;
|
|
||||||
|
|
||||||
NSMutableArray<ASTraceEvent *> *result = [NSMutableArray array];
|
|
||||||
|
|
||||||
// Start from `tail` and go through array, wrapping around when we exceed end index.
|
|
||||||
for (NSUInteger actualIndex = 0; actualIndex < ASDISPLAYNODE_EVENTLOG_CAPACITY; actualIndex++) {
|
|
||||||
NSInteger ringIndex = (tail + actualIndex) % ASDISPLAYNODE_EVENTLOG_CAPACITY;
|
|
||||||
if (ringIndex < count) {
|
|
||||||
[result addObject:_eventLog[ringIndex]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (UIView *)view
|
- (UIView *)view
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(!_flags.layerBacked, @"Call to -view undefined on layer-backed nodes");
|
ASDisplayNodeAssert(!_flags.layerBacked, @"Call to -view undefined on layer-backed nodes");
|
||||||
@ -3344,6 +3303,13 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
|
|||||||
|
|
||||||
#pragma mark Debugging (Private)
|
#pragma mark Debugging (Private)
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
- (ASEventLog *)eventLog
|
||||||
|
{
|
||||||
|
return _eventLog;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
|
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
|
||||||
{
|
{
|
||||||
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#import "ASTableNode.h"
|
#import "ASTableNode.h"
|
||||||
#import "ASTableViewInternal.h"
|
#import "ASTableViewInternal.h"
|
||||||
#import "ASEnvironmentInternal.h"
|
#import "ASEnvironmentInternal.h"
|
||||||
|
#import "ASDisplayNodeInternal.h"
|
||||||
#import "ASDisplayNode+Subclasses.h"
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
#import "ASCellNode+Internal.h"
|
#import "ASCellNode+Internal.h"
|
||||||
@ -79,7 +80,7 @@
|
|||||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass
|
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass
|
||||||
{
|
{
|
||||||
ASDisplayNodeViewBlock tableViewBlock = ^UIView *{
|
ASDisplayNodeViewBlock tableViewBlock = ^UIView *{
|
||||||
return [[ASTableView alloc] _initWithFrame:frame style:style dataControllerClass:dataControllerClass];
|
return [[ASTableView alloc] _initWithFrame:frame style:style dataControllerClass:dataControllerClass eventLog:ASDisplayNodeGetEventLog(self)];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self = [super initWithViewBlock:tableViewBlock]) {
|
if (self = [super initWithViewBlock:tableViewBlock]) {
|
||||||
@ -574,4 +575,14 @@ ASEnvironmentCollectionTableSetEnvironmentState(_environmentStateLock)
|
|||||||
[self.view waitUntilAllUpdatesAreCommitted];
|
[self.view waitUntilAllUpdatesAreCommitted];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Debugging (Private)
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [super propertiesForDebugDescription];
|
||||||
|
[result addObject:@{ @"dataSource" : ASObjectDescriptionMakeTiny(self.dataSource) }];
|
||||||
|
[result addObject:@{ @"delegate" : ASObjectDescriptionMakeTiny(self.delegate) }];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -212,7 +212,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark Lifecycle
|
#pragma mark Lifecycle
|
||||||
|
|
||||||
- (void)configureWithDataControllerClass:(Class)dataControllerClass
|
- (void)configureWithDataControllerClass:(Class)dataControllerClass eventLog:(ASEventLog *)eventLog
|
||||||
{
|
{
|
||||||
_layoutController = [[ASFlowLayoutController alloc] initWithScrollOption:ASFlowLayoutDirectionVertical];
|
_layoutController = [[ASFlowLayoutController alloc] initWithScrollOption:ASFlowLayoutDirectionVertical];
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
_rangeController.dataSource = self;
|
_rangeController.dataSource = self;
|
||||||
_rangeController.delegate = self;
|
_rangeController.delegate = self;
|
||||||
|
|
||||||
_dataController = [[dataControllerClass alloc] initWithDataSource:self];
|
_dataController = [[dataControllerClass alloc] initWithDataSource:self eventLog:eventLog];
|
||||||
_dataController.delegate = _rangeController;
|
_dataController.delegate = _rangeController;
|
||||||
_dataController.environmentDelegate = self;
|
_dataController.environmentDelegate = self;
|
||||||
|
|
||||||
@ -248,10 +248,10 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||||
{
|
{
|
||||||
return [self _initWithFrame:frame style:style dataControllerClass:nil];
|
return [self _initWithFrame:frame style:style dataControllerClass:nil eventLog:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass
|
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass eventLog:(ASEventLog *)eventLog
|
||||||
{
|
{
|
||||||
if (!(self = [super initWithFrame:frame style:style])) {
|
if (!(self = [super initWithFrame:frame style:style])) {
|
||||||
return nil;
|
return nil;
|
||||||
@ -261,7 +261,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
dataControllerClass = [[self class] dataControllerClass];
|
dataControllerClass = [[self class] dataControllerClass];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self configureWithDataControllerClass:dataControllerClass];
|
[self configureWithDataControllerClass:dataControllerClass eventLog:eventLog];
|
||||||
|
|
||||||
if (!AS_AT_LEAST_IOS9) {
|
if (!AS_AT_LEAST_IOS9) {
|
||||||
_retainedLayer = self.layer;
|
_retainedLayer = self.layer;
|
||||||
|
@ -31,8 +31,10 @@
|
|||||||
* @param style A constant that specifies the style of the table view. See UITableViewStyle for descriptions of valid constants.
|
* @param style A constant that specifies the style of the table view. See UITableViewStyle for descriptions of valid constants.
|
||||||
*
|
*
|
||||||
* @param dataControllerClass A controller class injected to and used to create a data controller for the table view.
|
* @param dataControllerClass A controller class injected to and used to create a data controller for the table view.
|
||||||
|
*
|
||||||
|
* @param eventLog An event log passed through to the data controller.
|
||||||
*/
|
*/
|
||||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass;
|
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass eventLog:(ASEventLog *)eventLog;
|
||||||
|
|
||||||
/// Set YES and we'll log every time we call [super insertRows…] etc
|
/// Set YES and we'll log every time we call [super insertRows…] etc
|
||||||
@property (nonatomic) BOOL test_enableSuperUpdateCallLogging;
|
@property (nonatomic) BOOL test_enableSuperUpdateCallLogging;
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
[_changeSet addCompletionHandler:completion];
|
[_changeSet addCompletionHandler:completion];
|
||||||
if (_changeSetBatchUpdateCounter == 0) {
|
if (_changeSetBatchUpdateCounter == 0) {
|
||||||
void (^batchCompletion)(BOOL finished) = _changeSet.completionHandler;
|
void (^batchCompletion)(BOOL) = _changeSet.completionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the initial reloadData has not been called, just bail because we don't have
|
* If the initial reloadData has not been called, just bail because we don't have
|
||||||
@ -66,6 +66,8 @@
|
|||||||
[self invalidateDataSourceItemCounts];
|
[self invalidateDataSourceItemCounts];
|
||||||
[_changeSet markCompletedWithNewItemCounts:[self itemCountsFromDataSource]];
|
[_changeSet markCompletedWithNewItemCounts:[self itemCountsFromDataSource]];
|
||||||
|
|
||||||
|
ASDataControllerLogEvent(self, @"triggeredUpdate: %@", _changeSet);
|
||||||
|
|
||||||
[super beginUpdates];
|
[super beginUpdates];
|
||||||
|
|
||||||
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeDelete]) {
|
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeDelete]) {
|
||||||
@ -84,6 +86,16 @@
|
|||||||
[super insertRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
|
[super insertRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
NSString *changeSetDescription = ASObjectDescriptionMakeTiny(_changeSet);
|
||||||
|
batchCompletion = ^(BOOL finished) {
|
||||||
|
if (batchCompletion != nil) {
|
||||||
|
batchCompletion(finished);
|
||||||
|
}
|
||||||
|
ASDataControllerLogEvent(self, @"finishedUpdate: %@", changeSetDescription);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
[super endUpdatesAnimated:animated completion:batchCompletion];
|
[super endUpdatesAnimated:animated completion:batchCompletion];
|
||||||
|
|
||||||
_changeSet = nil;
|
_changeSet = nil;
|
||||||
|
@ -43,7 +43,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@interface ASCollectionDataController : ASChangeSetDataController
|
@interface ASCollectionDataController : ASChangeSetDataController
|
||||||
|
|
||||||
- (instancetype)initWithDataSource:(id<ASCollectionDataControllerSource>)dataSource NS_DESIGNATED_INITIALIZER;
|
- (instancetype)initWithDataSource:(id<ASCollectionDataControllerSource>)dataSource eventLog:(nullable ASEventLog *)eventLog NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
- (ASCellNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
- (ASCellNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@
|
|||||||
NSMutableDictionary<NSString *, NSMutableArray<ASIndexedNodeContext *> *> *_pendingNodeContexts;
|
NSMutableDictionary<NSString *, NSMutableArray<ASIndexedNodeContext *> *> *_pendingNodeContexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithDataSource:(id<ASCollectionDataControllerSource>)dataSource
|
- (instancetype)initWithDataSource:(id<ASCollectionDataControllerSource>)dataSource eventLog:(ASEventLog *)eventLog
|
||||||
{
|
{
|
||||||
self = [super initWithDataSource:dataSource];
|
self = [super initWithDataSource:dataSource eventLog:eventLog];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
_pendingNodeContexts = [NSMutableDictionary dictionary];
|
_pendingNodeContexts = [NSMutableDictionary dictionary];
|
||||||
_dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath = [dataSource respondsToSelector:@selector(dataController:supplementaryNodeBlockOfKind:atIndexPath:)];
|
_dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath = [dataSource respondsToSelector:@selector(dataController:supplementaryNodeBlockOfKind:atIndexPath:)];
|
||||||
|
@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@class ASRangeController;
|
@class ASRangeController;
|
||||||
|
|
||||||
@interface ASCollectionView ()
|
@interface ASCollectionView ()
|
||||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator;
|
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator eventLog:(ASEventLog*)eventLog;
|
||||||
|
|
||||||
@property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode;
|
@property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode;
|
||||||
@property (nonatomic, strong, readonly) ASDataController *dataController;
|
@property (nonatomic, strong, readonly) ASDataController *dataController;
|
||||||
|
@ -14,9 +14,16 @@
|
|||||||
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
|
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
|
||||||
#import <AsyncDisplayKit/ASDimension.h>
|
#import <AsyncDisplayKit/ASDimension.h>
|
||||||
#import <AsyncDisplayKit/ASFlowLayoutController.h>
|
#import <AsyncDisplayKit/ASFlowLayoutController.h>
|
||||||
|
#import <AsyncDisplayKit/ASEventLog.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
#define ASDataControllerLogEvent(dataController, ...) [dataController.eventLog logEventWithBacktrace:[NSThread callStackSymbols] format:__VA_ARGS__]
|
||||||
|
#else
|
||||||
|
#define ASDataControllerLogEvent(dataController, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
@class ASCellNode;
|
@class ASCellNode;
|
||||||
@class ASDataController;
|
@class ASDataController;
|
||||||
@protocol ASEnvironment;
|
@protocol ASEnvironment;
|
||||||
@ -109,7 +116,7 @@ FOUNDATION_EXPORT NSString * const ASDataControllerRowNodeKind;
|
|||||||
@protocol ASFlowLayoutControllerDataSource;
|
@protocol ASFlowLayoutControllerDataSource;
|
||||||
@interface ASDataController : ASDealloc2MainObject <ASFlowLayoutControllerDataSource>
|
@interface ASDataController : ASDealloc2MainObject <ASFlowLayoutControllerDataSource>
|
||||||
|
|
||||||
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource NS_DESIGNATED_INITIALIZER;
|
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource eventLog:(nullable ASEventLog *)eventLog NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Data source for fetching data info.
|
Data source for fetching data info.
|
||||||
@ -135,6 +142,13 @@ FOUNDATION_EXPORT NSString * const ASDataControllerRowNodeKind;
|
|||||||
*/
|
*/
|
||||||
@property (nonatomic, readonly) BOOL initialReloadDataHasBeenCalled;
|
@property (nonatomic, readonly) BOOL initialReloadDataHasBeenCalled;
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
/*
|
||||||
|
* @abstract The primitive event tracing object. You shouldn't directly use it to log event. Use the ASDataControllerLogEvent macro instead.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, strong, readonly) ASEventLog *eventLog;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @name Data Updating */
|
/** @name Data Updating */
|
||||||
|
|
||||||
- (void)beginUpdates;
|
- (void)beginUpdates;
|
||||||
|
@ -71,7 +71,7 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
|||||||
|
|
||||||
#pragma mark - Lifecycle
|
#pragma mark - Lifecycle
|
||||||
|
|
||||||
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource
|
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource eventLog:(ASEventLog *)eventLog
|
||||||
{
|
{
|
||||||
if (!(self = [super init])) {
|
if (!(self = [super init])) {
|
||||||
return nil;
|
return nil;
|
||||||
@ -80,6 +80,10 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
|||||||
|
|
||||||
_dataSource = dataSource;
|
_dataSource = dataSource;
|
||||||
|
|
||||||
|
#if ASEVENTLOG_ENABLE
|
||||||
|
_eventLog = eventLog;
|
||||||
|
#endif
|
||||||
|
|
||||||
_nodeContexts = [NSMutableDictionary dictionary];
|
_nodeContexts = [NSMutableDictionary dictionary];
|
||||||
_completedNodes = [NSMutableDictionary dictionary];
|
_completedNodes = [NSMutableDictionary dictionary];
|
||||||
_editingNodes = [NSMutableDictionary dictionary];
|
_editingNodes = [NSMutableDictionary dictionary];
|
||||||
@ -102,7 +106,8 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
|||||||
{
|
{
|
||||||
ASDisplayNodeFailAssert(@"Failed to call designated initializer.");
|
ASDisplayNodeFailAssert(@"Failed to call designated initializer.");
|
||||||
id<ASDataControllerSource> fakeDataSource = nil;
|
id<ASDataControllerSource> fakeDataSource = nil;
|
||||||
return [self initWithDataSource:fakeDataSource];
|
ASEventLog *eventLog = nil;
|
||||||
|
return [self initWithDataSource:fakeDataSource eventLog:eventLog];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDelegate:(id<ASDataControllerDelegate>)delegate
|
- (void)setDelegate:(id<ASDataControllerDelegate>)delegate
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// ASObjectDescriptions.h
|
// ASObjectDescriptionHelpers.h
|
||||||
// AsyncDisplayKit
|
// AsyncDisplayKit
|
||||||
//
|
//
|
||||||
// Created by Adlai Holler on 9/7/16.
|
// Created by Adlai Holler on 9/7/16.
|
||||||
@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
/**
|
/**
|
||||||
* Your base class should conform to this and override `-description`
|
* Your base class should conform to this and override `-description`
|
||||||
* to call `[self propertiesForDescription]` and use `ASObjectDescriptionMake`
|
* to call `[self propertiesForDescription]` and use `ASObjectDescriptionMake`
|
||||||
* to return a string. Subclasses of this base class just need to override
|
* to return a string. Subclasses of this base class just need to override
|
||||||
* `propertiesForDescription`, call super, and modify the result as needed.
|
* `propertiesForDescription`, call super, and modify the result as needed.
|
||||||
*/
|
*/
|
||||||
@protocol ASDescriptionProvider
|
@protocol ASDescriptionProvider
|
||||||
@ -36,6 +36,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
ASDISPLAYNODE_EXTERN_C_BEGIN
|
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
NSString *ASGetDescriptionValueString(id object);
|
||||||
|
|
||||||
/// Useful for structs etc. Returns e.g. { position = (0 0); frame = (0 0; 50 50) }
|
/// Useful for structs etc. Returns e.g. { position = (0 0); frame = (0 0; 50 50) }
|
||||||
NSString *ASObjectDescriptionMakeWithoutObject(NSArray<NSDictionary *> * _Nullable propertyGroups);
|
NSString *ASObjectDescriptionMakeWithoutObject(NSArray<NSDictionary *> * _Nullable propertyGroups);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// ASObjectDescriptions.m
|
// ASObjectDescriptionHelpers.m
|
||||||
// AsyncDisplayKit
|
// AsyncDisplayKit
|
||||||
//
|
//
|
||||||
// Created by Adlai Holler on 9/7/16.
|
// Created by Adlai Holler on 9/7/16.
|
||||||
|
@ -122,10 +122,11 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
|
|||||||
|
|
||||||
UIEdgeInsets _hitTestSlop;
|
UIEdgeInsets _hitTestSlop;
|
||||||
NSMutableArray *_subnodes;
|
NSMutableArray *_subnodes;
|
||||||
NSMutableArray<ASTraceEvent *> *_eventLog;
|
|
||||||
// The index of the most recent log entry. -1 until first entry.
|
#if ASEVENTLOG_ENABLE
|
||||||
NSInteger _eventLogHead;
|
ASEventLog *_eventLog;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Main thread only
|
// Main thread only
|
||||||
BOOL _automaticallyManagesSubnodes;
|
BOOL _automaticallyManagesSubnodes;
|
||||||
_ASTransitionContext *_pendingLayoutTransitionContext;
|
_ASTransitionContext *_pendingLayoutTransitionContext;
|
||||||
|
25
AsyncDisplayKit/Private/ASEventLog.h
Normal file
25
AsyncDisplayKit/Private/ASEventLog.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// ASEventLog.h
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Huy Nguyen on 4/11/16.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASEVENTLOG_CAPACITY
|
||||||
|
#define ASEVENTLOG_CAPACITY 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASEVENTLOG_ENABLE
|
||||||
|
#define ASEVENTLOG_ENABLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@interface ASEventLog : NSObject
|
||||||
|
|
||||||
|
- (void)logEventWithBacktrace:(NSArray<NSString *> *)backtrace format:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3);
|
||||||
|
|
||||||
|
@end
|
80
AsyncDisplayKit/Private/ASEventLog.mm
Normal file
80
AsyncDisplayKit/Private/ASEventLog.mm
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// ASEventLog.m
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Huy Nguyen on 4/11/16.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ASEventLog.h"
|
||||||
|
#import "ASThread.h"
|
||||||
|
#import "ASTraceEvent.h"
|
||||||
|
|
||||||
|
@interface ASEventLog ()
|
||||||
|
{
|
||||||
|
ASDN::RecursiveMutex __instanceLock__;
|
||||||
|
// The index of the most recent log entry. -1 until first entry.
|
||||||
|
NSInteger _eventLogHead;
|
||||||
|
// The most recent trace events. Max count is ASEVENTLOG_CAPACITY.
|
||||||
|
NSMutableArray<ASTraceEvent *> *_eventLog;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ASEventLog
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_eventLogHead = -1;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)logEventWithBacktrace:(NSArray<NSString *> *)backtrace format:(NSString *)format, ...
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
ASTraceEvent *event = [[ASTraceEvent alloc] initWithObject:self
|
||||||
|
backtrace:backtrace
|
||||||
|
format:format
|
||||||
|
arguments:args];
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
// Create the array if needed.
|
||||||
|
if (_eventLog == nil) {
|
||||||
|
_eventLog = [NSMutableArray arrayWithCapacity:ASEVENTLOG_CAPACITY];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the head index.
|
||||||
|
_eventLogHead = (_eventLogHead + 1) % ASEVENTLOG_CAPACITY;
|
||||||
|
if (_eventLogHead < _eventLog.count) {
|
||||||
|
[_eventLog replaceObjectAtIndex:_eventLogHead withObject:event];
|
||||||
|
} else {
|
||||||
|
[_eventLog insertObject:event atIndex:_eventLogHead];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<ASTraceEvent *> *)eventLog
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
NSUInteger tail = (_eventLogHead + 1);
|
||||||
|
NSUInteger count = _eventLog.count;
|
||||||
|
|
||||||
|
NSMutableArray<ASTraceEvent *> *result = [NSMutableArray array];
|
||||||
|
|
||||||
|
// Start from `tail` and go through array, wrapping around when we exceed end index.
|
||||||
|
for (NSUInteger actualIndex = 0; actualIndex < ASEVENTLOG_CAPACITY; actualIndex++) {
|
||||||
|
NSInteger ringIndex = (tail + actualIndex) % ASEVENTLOG_CAPACITY;
|
||||||
|
if (ringIndex < count) {
|
||||||
|
[result addObject:_eventLog[ringIndex]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <vector>
|
#import <vector>
|
||||||
|
#import "ASObjectDescriptionHelpers.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ BOOL ASHierarchyChangeTypeIsFinal(_ASHierarchyChangeType changeType);
|
|||||||
|
|
||||||
NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
|
NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
|
||||||
|
|
||||||
@interface _ASHierarchySectionChange : NSObject
|
@interface _ASHierarchySectionChange : NSObject <ASDescriptionProvider, ASDebugDescriptionProvider>
|
||||||
|
|
||||||
// FIXME: Generalize this to `changeMetadata` dict?
|
// FIXME: Generalize this to `changeMetadata` dict?
|
||||||
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
|
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
|
||||||
@ -73,7 +74,7 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
|
|||||||
- (_ASHierarchySectionChange *)changeByFinalizingType;
|
- (_ASHierarchySectionChange *)changeByFinalizingType;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface _ASHierarchyItemChange : NSObject
|
@interface _ASHierarchyItemChange : NSObject <ASDescriptionProvider, ASDebugDescriptionProvider>
|
||||||
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
|
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
|
||||||
|
|
||||||
/// Index paths are sorted descending for changeType .Delete, ascending otherwise
|
/// Index paths are sorted descending for changeType .Delete, ascending otherwise
|
||||||
@ -81,7 +82,7 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
|
|||||||
|
|
||||||
@property (nonatomic, readonly) _ASHierarchyChangeType changeType;
|
@property (nonatomic, readonly) _ASHierarchyChangeType changeType;
|
||||||
|
|
||||||
+ (NSDictionary *)sectionToIndexSetMapFromChanges:(NSArray<_ASHierarchyItemChange *> *)changes ofType:(_ASHierarchyChangeType)changeType;
|
+ (NSDictionary *)sectionToIndexSetMapFromChanges:(NSArray<_ASHierarchyItemChange *> *)changes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is a .OriginalInsert or .OriginalDelete change, this returns a copied change
|
* If this is a .OriginalInsert or .OriginalDelete change, this returns a copied change
|
||||||
@ -90,7 +91,7 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
|
|||||||
- (_ASHierarchyItemChange *)changeByFinalizingType;
|
- (_ASHierarchyItemChange *)changeByFinalizingType;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface _ASHierarchyChangeSet : NSObject
|
@interface _ASHierarchyChangeSet : NSObject <ASDescriptionProvider, ASDebugDescriptionProvider>
|
||||||
|
|
||||||
- (instancetype)initWithOldData:(std::vector<NSInteger>)oldItemCounts NS_DESIGNATED_INITIALIZER;
|
- (instancetype)initWithOldData:(std::vector<NSInteger>)oldItemCounts NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#import "NSIndexSet+ASHelpers.h"
|
#import "NSIndexSet+ASHelpers.h"
|
||||||
#import "ASAssert.h"
|
#import "ASAssert.h"
|
||||||
#import "ASDisplayNode+Beta.h"
|
#import "ASDisplayNode+Beta.h"
|
||||||
|
#import "ASObjectDescriptionHelpers.h"
|
||||||
#import <unordered_map>
|
#import <unordered_map>
|
||||||
|
|
||||||
// NOTE: We log before throwing so they don't have to let it bubble up to see the error.
|
// NOTE: We log before throwing so they don't have to let it bubble up to see the error.
|
||||||
@ -66,6 +66,8 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
|
|
||||||
/// Returns all the indexes from all the `indexSet`s of the given `_ASHierarchySectionChange` objects.
|
/// Returns all the indexes from all the `indexSet`s of the given `_ASHierarchySectionChange` objects.
|
||||||
+ (NSMutableIndexSet *)allIndexesInSectionChanges:(NSArray *)changes;
|
+ (NSMutableIndexSet *)allIndexesInSectionChanges:(NSArray *)changes;
|
||||||
|
|
||||||
|
+ (NSString *)smallDescriptionForSectionChanges:(NSArray<_ASHierarchySectionChange *> *)changes;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface _ASHierarchyItemChange ()
|
@interface _ASHierarchyItemChange ()
|
||||||
@ -76,9 +78,13 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
Assumes: `changes` all have the same changeType
|
Assumes: `changes` all have the same changeType
|
||||||
*/
|
*/
|
||||||
+ (void)sortAndCoalesceItemChanges:(NSMutableArray<_ASHierarchyItemChange *> *)changes ignoringChangesInSections:(NSIndexSet *)sections;
|
+ (void)sortAndCoalesceItemChanges:(NSMutableArray<_ASHierarchyItemChange *> *)changes ignoringChangesInSections:(NSIndexSet *)sections;
|
||||||
|
|
||||||
|
+ (NSString *)smallDescriptionForItemChanges:(NSArray<_ASHierarchyItemChange *> *)changes;
|
||||||
|
|
||||||
|
+ (void)ensureItemChanges:(NSArray<_ASHierarchyItemChange *> *)changes ofSameType:(_ASHierarchyChangeType)changeType;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface _ASHierarchyChangeSet ()
|
@interface _ASHierarchyChangeSet ()
|
||||||
|
|
||||||
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *insertItemChanges;
|
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *insertItemChanges;
|
||||||
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *originalInsertItemChanges;
|
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *originalInsertItemChanges;
|
||||||
@ -328,8 +334,11 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
[_insertItemChanges addObject:[originalInsertItemChange changeByFinalizingType]];
|
[_insertItemChanges addObject:[originalInsertItemChange changeByFinalizingType]];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSDictionary *insertedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_insertItemChanges ofType:_ASHierarchyChangeTypeInsert];
|
[_ASHierarchyItemChange ensureItemChanges:_insertItemChanges ofSameType:_ASHierarchyChangeTypeInsert];
|
||||||
NSDictionary *deletedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_deleteItemChanges ofType:_ASHierarchyChangeTypeDelete];
|
NSDictionary *insertedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_insertItemChanges];
|
||||||
|
|
||||||
|
[_ASHierarchyItemChange ensureItemChanges:_deleteItemChanges ofSameType:_ASHierarchyChangeTypeDelete];
|
||||||
|
NSDictionary *deletedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_deleteItemChanges];
|
||||||
|
|
||||||
for (_ASHierarchyItemChange *change in _reloadItemChanges) {
|
for (_ASHierarchyItemChange *change in _reloadItemChanges) {
|
||||||
NSAssert(change.changeType == _ASHierarchyChangeTypeReload, @"It must be a reload change to be in here");
|
NSAssert(change.changeType == _ASHierarchyChangeTypeReload, @"It must be a reload change to be in here");
|
||||||
@ -484,11 +493,46 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Debugging (Private)
|
||||||
|
|
||||||
- (NSString *)description
|
- (NSString *)description
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat:@"<%@ %p: deletedSections=%@, insertedSections=%@, deletedItems=%@, insertedItems=%@>", NSStringFromClass(self.class), self, _deletedSections, _insertedSections, _deleteItemChanges, _insertItemChanges];
|
return ASObjectDescriptionMake(self, [self propertiesForDescription]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)debugDescription
|
||||||
|
{
|
||||||
|
return ASObjectDescriptionMake(self, [self propertiesForDebugDescription]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
||||||
|
if (_reloadSectionChanges.count > 0) {
|
||||||
|
[result addObject:@{ @"reloadSections" : [_ASHierarchySectionChange smallDescriptionForSectionChanges:_reloadSectionChanges] }];
|
||||||
|
}
|
||||||
|
if (_reloadItemChanges.count > 0) {
|
||||||
|
[result addObject:@{ @"reloadItems" : [_ASHierarchyItemChange smallDescriptionForItemChanges:_reloadItemChanges] }];
|
||||||
|
}
|
||||||
|
if (_originalDeleteSectionChanges.count > 0) {
|
||||||
|
[result addObject:@{ @"deleteSections" : [_ASHierarchySectionChange smallDescriptionForSectionChanges:_originalDeleteSectionChanges] }];
|
||||||
|
}
|
||||||
|
if (_originalDeleteItemChanges.count > 0) {
|
||||||
|
[result addObject:@{ @"deleteItems" : [_ASHierarchyItemChange smallDescriptionForItemChanges:_originalDeleteItemChanges] }];
|
||||||
|
}
|
||||||
|
if (_originalInsertSectionChanges.count > 0) {
|
||||||
|
[result addObject:@{ @"insertSections" : [_ASHierarchySectionChange smallDescriptionForSectionChanges:_originalInsertSectionChanges] }];
|
||||||
|
}
|
||||||
|
if (_originalInsertItemChanges.count > 0) {
|
||||||
|
[result addObject:@{ @"insertItems" : [_ASHierarchyItemChange smallDescriptionForItemChanges:_originalInsertItemChanges] }];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
|
||||||
|
{
|
||||||
|
return [self propertiesForDescription];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -600,9 +644,46 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
return indexes;
|
return indexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Debugging (Private)
|
||||||
|
|
||||||
|
+ (NSString *)smallDescriptionForSectionChanges:(NSArray<_ASHierarchySectionChange *> *)changes
|
||||||
|
{
|
||||||
|
NSMutableIndexSet *unionIndexSet = [NSMutableIndexSet indexSet];
|
||||||
|
for (_ASHierarchySectionChange *change in changes) {
|
||||||
|
[unionIndexSet addIndexes:change.indexSet];
|
||||||
|
}
|
||||||
|
return [unionIndexSet as_smallDescription];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString *)description
|
- (NSString *)description
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat:@"<%@: anim=%lu, type=%@, indexes=%@>", NSStringFromClass(self.class), (unsigned long)_animationOptions, NSStringFromASHierarchyChangeType(_changeType), [self.indexSet as_smallDescription]];
|
return ASObjectDescriptionMake(self, [self propertiesForDescription]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)debugDescription
|
||||||
|
{
|
||||||
|
return ASObjectDescriptionMake(self, [self propertiesForDebugDescription]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)smallDescription
|
||||||
|
{
|
||||||
|
return [self.indexSet as_smallDescription];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
||||||
|
[result addObject:@{ @"indexes" : [self.indexSet as_smallDescription] }];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
||||||
|
[result addObject:@{ @"anim" : @(_animationOptions) }];
|
||||||
|
[result addObject:@{ @"type" : NSStringFromASHierarchyChangeType(_changeType) }];
|
||||||
|
[result addObject:@{ @"indexes" : self.indexSet }];
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -629,11 +710,10 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
// Create a mapping out of changes indexPaths to a {@section : [indexSet]} fashion
|
// Create a mapping out of changes indexPaths to a {@section : [indexSet]} fashion
|
||||||
// e.g. changes: (0 - 0), (0 - 1), (2 - 5)
|
// e.g. changes: (0 - 0), (0 - 1), (2 - 5)
|
||||||
// will become: {@0 : [0, 1], @2 : [5]}
|
// will become: {@0 : [0, 1], @2 : [5]}
|
||||||
+ (NSDictionary *)sectionToIndexSetMapFromChanges:(NSArray *)changes ofType:(_ASHierarchyChangeType)changeType
|
+ (NSDictionary *)sectionToIndexSetMapFromChanges:(NSArray<_ASHierarchyItemChange *> *)changes
|
||||||
{
|
{
|
||||||
NSMutableDictionary *sectionToIndexSetMap = [NSMutableDictionary dictionary];
|
NSMutableDictionary *sectionToIndexSetMap = [NSMutableDictionary dictionary];
|
||||||
for (_ASHierarchyItemChange *change in changes) {
|
for (_ASHierarchyItemChange *change in changes) {
|
||||||
NSAssert(change.changeType == changeType, @"The map we created must all be of the same changeType as of now");
|
|
||||||
for (NSIndexPath *indexPath in change.indexPaths) {
|
for (NSIndexPath *indexPath in change.indexPaths) {
|
||||||
NSNumber *sectionKey = @(indexPath.section);
|
NSNumber *sectionKey = @(indexPath.section);
|
||||||
NSMutableIndexSet *indexSet = sectionToIndexSetMap[sectionKey];
|
NSMutableIndexSet *indexSet = sectionToIndexSetMap[sectionKey];
|
||||||
@ -648,6 +728,13 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
return sectionToIndexSetMap;
|
return sectionToIndexSetMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void)ensureItemChanges:(NSArray<_ASHierarchyItemChange *> *)changes ofSameType:(_ASHierarchyChangeType)changeType
|
||||||
|
{
|
||||||
|
for (_ASHierarchyItemChange *change in changes) {
|
||||||
|
NSAssert(change.changeType == changeType, @"The map we created must all be of the same changeType as of now");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (_ASHierarchyItemChange *)changeByFinalizingType
|
- (_ASHierarchyItemChange *)changeByFinalizingType
|
||||||
{
|
{
|
||||||
_ASHierarchyChangeType newType;
|
_ASHierarchyChangeType newType;
|
||||||
@ -725,9 +812,43 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
|
|||||||
[changes setArray:result];
|
[changes setArray:result];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Debugging (Private)
|
||||||
|
|
||||||
|
+ (NSString *)smallDescriptionForItemChanges:(NSArray<_ASHierarchyItemChange *> *)changes
|
||||||
|
{
|
||||||
|
NSDictionary *map = [self sectionToIndexSetMapFromChanges:changes];
|
||||||
|
NSMutableString *str = [NSMutableString stringWithString:@"{ "];
|
||||||
|
[map enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull section, NSIndexSet * _Nonnull indexSet, BOOL * _Nonnull stop) {
|
||||||
|
[str appendFormat:@"@%lu : %@ ", section.integerValue, [indexSet as_smallDescription]];
|
||||||
|
}];
|
||||||
|
[str appendString:@"}"];
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString *)description
|
- (NSString *)description
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat:@"<%@: anim=%lu, type=%@, indexPaths=%@>", NSStringFromClass(self.class), (unsigned long)_animationOptions, NSStringFromASHierarchyChangeType(_changeType), self.indexPaths];
|
return ASObjectDescriptionMake(self, [self propertiesForDescription]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)debugDescription
|
||||||
|
{
|
||||||
|
return ASObjectDescriptionMake(self, [self propertiesForDebugDescription]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
||||||
|
[result addObject:@{ @"indexPaths" : self.indexPaths }];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray<NSDictionary *> *)propertiesForDebugDescription
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary *> *result = [NSMutableArray array];
|
||||||
|
[result addObject:@{ @"anim" : @(_animationOptions) }];
|
||||||
|
[result addObject:@{ @"type" : NSStringFromASHierarchyChangeType(_changeType) }];
|
||||||
|
[result addObject:@{ @"indexPaths" : self.indexPaths }];
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -53,7 +53,8 @@
|
|||||||
|
|
||||||
- (instancetype)__initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
- (instancetype)__initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||||
{
|
{
|
||||||
return [super _initWithFrame:frame style:style dataControllerClass:[ASTestDataController class]];
|
|
||||||
|
return [super _initWithFrame:frame style:style dataControllerClass:[ASTestDataController class] eventLog:[[ASEventLog alloc] init]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASTestDataController *)testDataController
|
- (ASTestDataController *)testDataController
|
||||||
|
Loading…
x
Reference in New Issue
Block a user