mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-11 17:00:02 +00:00
Merge commit '67cb789f862fa7572a06159c230612ef3ad414c4'
# Conflicts: # AsyncDisplayKit/Details/ASEventLog.h
This commit is contained in:
commit
c9487b2d17
@ -184,6 +184,11 @@
|
||||
68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */; };
|
||||
68B8A4E31CBDB958007E4543 /* ASWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */; };
|
||||
68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */; };
|
||||
68C215581DE10D330019C4BC /* ASCollectionViewLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
68C215591DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */; };
|
||||
68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */; };
|
||||
68C2155B1DE11A790019C4BC /* ASCollectionViewLayoutInspector.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */; };
|
||||
68C2155C1DE11AA80019C4BC /* ASObjectDescriptionHelpers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */; };
|
||||
68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */; };
|
||||
68EE0DBF1C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; };
|
||||
68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; };
|
||||
@ -439,7 +444,7 @@
|
||||
CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; };
|
||||
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */; };
|
||||
CC4981BD1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */; };
|
||||
CC4C2A771D88E3BF0039ACAB /* ASTraceEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4C2A751D88E3BF0039ACAB /* ASTraceEvent.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC4C2A771D88E3BF0039ACAB /* ASTraceEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4C2A751D88E3BF0039ACAB /* ASTraceEvent.h */; };
|
||||
CC4C2A781D88E3BF0039ACAB /* ASTraceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */; };
|
||||
CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */; };
|
||||
CC4C2A7A1D8902350039ACAB /* ASTraceEvent.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CC4C2A751D88E3BF0039ACAB /* ASTraceEvent.h */; };
|
||||
@ -475,7 +480,7 @@
|
||||
DE89C1701DCEB9CC00D49D74 /* ASLayoutElementInspectorCell.h in Headers */ = {isa = PBXBuildFile; fileRef = DE89C16A1DCEB9CC00D49D74 /* ASLayoutElementInspectorCell.h */; };
|
||||
DE89C1711DCEB9CC00D49D74 /* ASLayoutElementInspectorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DE89C16B1DCEB9CC00D49D74 /* ASLayoutElementInspectorCell.m */; };
|
||||
DE89C1731DCEB9CC00D49D74 /* ASLayoutElementInspectorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DE89C16B1DCEB9CC00D49D74 /* ASLayoutElementInspectorCell.m */; };
|
||||
DE89C1741DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DE89C16C1DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
DE89C1741DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DE89C16C1DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.h */; };
|
||||
DE89C1751DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.m in Sources */ = {isa = PBXBuildFile; fileRef = DE89C16D1DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.m */; };
|
||||
DE89C1771DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.m in Sources */ = {isa = PBXBuildFile; fileRef = DE89C16D1DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.m */; };
|
||||
DE89C1781DCEB9CC00D49D74 /* ASLayoutSpec+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = DE89C16E1DCEB9CC00D49D74 /* ASLayoutSpec+Debug.h */; };
|
||||
@ -667,6 +672,8 @@
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
68C2155C1DE11AA80019C4BC /* ASObjectDescriptionHelpers.h in CopyFiles */,
|
||||
68C2155B1DE11A790019C4BC /* ASCollectionViewLayoutInspector.h in CopyFiles */,
|
||||
DEB8ED7E1DD007F400DBDE55 /* ASLayoutElementInspectorNode.h in CopyFiles */,
|
||||
69127CFE1DD2B387004BF6E2 /* ASEventLog.h in CopyFiles */,
|
||||
693117CE1DC7C72700DE4784 /* ASDisplayNode+Deprecated.h in CopyFiles */,
|
||||
@ -983,6 +990,8 @@
|
||||
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+AnimatedImagePrivate.h"; sourceTree = "<group>"; };
|
||||
68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakProxy.h; sourceTree = "<group>"; };
|
||||
68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakProxy.m; sourceTree = "<group>"; };
|
||||
68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutInspector.h; sourceTree = "<group>"; };
|
||||
68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewLayoutInspector.m; sourceTree = "<group>"; };
|
||||
68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMainSerialQueue.h; sourceTree = "<group>"; };
|
||||
68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = "<group>"; };
|
||||
68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASNavigationController.h; sourceTree = "<group>"; };
|
||||
@ -1484,6 +1493,8 @@
|
||||
054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */,
|
||||
299DA1A71A828D2900162D41 /* ASBatchContext.h */,
|
||||
299DA1A81A828D2900162D41 /* ASBatchContext.mm */,
|
||||
68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */,
|
||||
68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */,
|
||||
251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */,
|
||||
251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */,
|
||||
205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */,
|
||||
@ -1810,6 +1821,7 @@
|
||||
DE89C1741DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.h in Headers */,
|
||||
B13CA1011C52004900E031AB /* ASCollectionNode+Beta.h in Headers */,
|
||||
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
|
||||
68C215581DE10D330019C4BC /* ASCollectionViewLayoutInspector.h in Headers */,
|
||||
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */,
|
||||
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */,
|
||||
B350620F1B010EFD0018CF92 /* _ASDisplayLayer.h in Headers */,
|
||||
@ -2285,6 +2297,7 @@
|
||||
ACF6ED321B17843500DA7C62 /* ASAbsoluteLayoutSpec.mm in Sources */,
|
||||
AC026B6B1BD57D6F00BBC17E /* ASChangeSetDataController.mm in Sources */,
|
||||
68355B311CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */,
|
||||
68C215591DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */,
|
||||
9CFFC6C01CCAC73C006A6476 /* ASViewController.mm in Sources */,
|
||||
055F1A3519ABD3E3004DAFF1 /* ASTableView.mm in Sources */,
|
||||
6959433E1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */,
|
||||
@ -2474,6 +2487,7 @@
|
||||
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.mm in Sources */,
|
||||
34EFC7741B701D0A00AD841F /* ASAbsoluteLayoutSpec.mm in Sources */,
|
||||
92074A6A1CC8BADA00918F75 /* ASControlNode+tvOS.m in Sources */,
|
||||
68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */,
|
||||
DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.m in Sources */,
|
||||
B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */,
|
||||
B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */,
|
||||
|
||||
@ -121,8 +121,10 @@
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator
|
||||
{
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
ASDisplayNodeViewBlock collectionViewBlock = ^UIView *{
|
||||
return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:layoutFacilitator eventLog:ASDisplayNodeGetEventLog(self)];
|
||||
__typeof__(self) strongSelf = weakSelf;
|
||||
return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:layoutFacilitator eventLog:ASDisplayNodeGetEventLog(strongSelf)];
|
||||
};
|
||||
|
||||
if (self = [super initWithViewBlock:collectionViewBlock]) {
|
||||
|
||||
@ -38,24 +38,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface ASCollectionView : UICollectionView
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous delegate of the collection view
|
||||
*
|
||||
* @discussion The delegate must adopt the ASCollectionDelegate protocol. The collection view maintains a weak reference to the delegate object.
|
||||
*
|
||||
* The delegate object is responsible for providing size constraints for nodes and indicating whether batch fetching should begin.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCollectionDelegate> asyncDelegate;
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous data source of the collection view
|
||||
*
|
||||
* @discussion The datasource must adopt the ASCollectionDataSource protocol. The collection view maintains a weak reference to the datasource object.
|
||||
*
|
||||
* The datasource object is responsible for providing nodes or node creation blocks to the collection view.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCollectionDataSource> asyncDataSource;
|
||||
|
||||
/**
|
||||
* Returns the corresponding ASCollectionNode
|
||||
*
|
||||
@ -138,6 +120,24 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ASCollectionView (Deprecated)
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous delegate of the collection view
|
||||
*
|
||||
* @discussion The delegate must adopt the ASCollectionDelegate protocol. The collection view maintains a weak reference to the delegate object.
|
||||
*
|
||||
* The delegate object is responsible for providing size constraints for nodes and indicating whether batch fetching should begin.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCollectionDelegate> asyncDelegate ASDISPLAYNODE_DEPRECATED_MSG("Please use ASCollectionNode's .delegate property instead.");
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous data source of the collection view
|
||||
*
|
||||
* @discussion The datasource must adopt the ASCollectionDataSource protocol. The collection view maintains a weak reference to the datasource object.
|
||||
*
|
||||
* The datasource object is responsible for providing nodes or node creation blocks to the collection view.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCollectionDataSource> asyncDataSource ASDISPLAYNODE_DEPRECATED_MSG("Please use ASCollectionNode's .dataSource property instead.");
|
||||
|
||||
/**
|
||||
* Initializes an ASCollectionView
|
||||
*
|
||||
|
||||
@ -224,8 +224,10 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
@end
|
||||
|
||||
@implementation ASCollectionView
|
||||
@synthesize asyncDelegate = _asyncDelegate;
|
||||
@synthesize asyncDataSource = _asyncDataSource;
|
||||
{
|
||||
__weak id<ASCollectionDelegate> _asyncDelegate;
|
||||
__weak id<ASCollectionDataSource> _asyncDataSource;
|
||||
}
|
||||
|
||||
// Using _ASDisplayLayer ensures things like -layout are properly forwarded to ASCollectionNode.
|
||||
+ (Class)layerClass
|
||||
@ -368,6 +370,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
}
|
||||
}
|
||||
|
||||
- (id<ASCollectionDataSource>)asyncDataSource
|
||||
{
|
||||
return _asyncDataSource;
|
||||
}
|
||||
|
||||
- (void)setAsyncDataSource:(id<ASCollectionDataSource>)asyncDataSource
|
||||
{
|
||||
// Changing super.dataSource will trigger a setNeedsLayout, so this must happen on the main thread.
|
||||
@ -418,6 +425,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
}
|
||||
}
|
||||
|
||||
- (id<ASCollectionDelegate>)asyncDelegate
|
||||
{
|
||||
return _asyncDelegate;
|
||||
}
|
||||
|
||||
- (void)setAsyncDelegate:(id<ASCollectionDelegate>)asyncDelegate
|
||||
{
|
||||
// Changing super.delegate will trigger a setNeedsLayout, so this must happen on the main thread.
|
||||
|
||||
@ -307,7 +307,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
[self _staticInitialize];
|
||||
|
||||
#if ASEVENTLOG_ENABLE
|
||||
_eventLog = [[ASEventLog alloc] init];
|
||||
_eventLog = [[ASEventLog alloc] initWithObject:self];
|
||||
#endif
|
||||
|
||||
_contentsScaleForDisplay = ASScreenScale();
|
||||
@ -2624,9 +2624,13 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
{
|
||||
__ASDisplayNodeCheckForLayoutMethodOverrides;
|
||||
|
||||
ASDisplayNodeAssert(ASIsCGSizeValidForSize(constrainedSize), @"Cannot calculate size of node because constrained size is infinite and node does not override -calculateSizeThatFits:. Try setting style.preferredSize on the node. Node: %@", self);
|
||||
#if ASDISPLAYNODE_ASSERTIONS_ENABLED
|
||||
if (ASIsCGSizeValidForSize(constrainedSize) == NO) {
|
||||
NSLog(@"Cannot calculate size of node: constrainedSize is infinite and node does not override -calculateSizeThatFits: or specify a preferredSize. Try setting style.preferredSize. Node: %@", [self displayNodeRecursiveDescription]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return constrainedSize;
|
||||
return ASIsCGSizeValidForSize(constrainedSize) ? constrainedSize : CGSizeZero;
|
||||
}
|
||||
|
||||
- (id<ASLayoutElement>)_layoutElementThatFits:(ASSizeRange)constrainedSize
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#import "ASPagerFlowLayout.h"
|
||||
#import "ASAssert.h"
|
||||
#import "ASCellNode.h"
|
||||
#import "ASCollectionView+Undeprecated.h"
|
||||
|
||||
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor>
|
||||
{
|
||||
|
||||
@ -79,8 +79,10 @@
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass
|
||||
{
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
ASDisplayNodeViewBlock tableViewBlock = ^UIView *{
|
||||
return [[ASTableView alloc] _initWithFrame:frame style:style dataControllerClass:dataControllerClass eventLog:ASDisplayNodeGetEventLog(self)];
|
||||
__typeof__(self) strongSelf = weakSelf;
|
||||
return [[ASTableView alloc] _initWithFrame:frame style:style dataControllerClass:dataControllerClass eventLog:ASDisplayNodeGetEventLog(strongSelf)];
|
||||
};
|
||||
|
||||
if (self = [super initWithViewBlock:tableViewBlock]) {
|
||||
|
||||
@ -38,9 +38,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// The corresponding table node, or nil if one does not exist.
|
||||
@property (nonatomic, weak, readonly) ASTableNode *tableNode;
|
||||
|
||||
@property (nonatomic, weak) id<ASTableDelegate> asyncDelegate;
|
||||
@property (nonatomic, weak) id<ASTableDataSource> asyncDataSource;
|
||||
|
||||
/**
|
||||
* Retrieves the node for the row at the given index path.
|
||||
*/
|
||||
@ -66,6 +63,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ASTableView (Deprecated)
|
||||
|
||||
@property (nonatomic, weak) id<ASTableDelegate> asyncDelegate ASDISPLAYNODE_DEPRECATED_MSG("Use ASTableNode's .delegate property instead.");
|
||||
@property (nonatomic, weak) id<ASTableDataSource> asyncDataSource ASDISPLAYNODE_DEPRECATED_MSG("Use ASTableNode .dataSource property instead.");
|
||||
|
||||
/**
|
||||
* Initializer.
|
||||
*
|
||||
|
||||
@ -197,6 +197,10 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
@end
|
||||
|
||||
@implementation ASTableView
|
||||
{
|
||||
__weak id<ASTableDelegate> _asyncDelegate;
|
||||
__weak id<ASTableDataSource> _asyncDataSource;
|
||||
}
|
||||
|
||||
// Using _ASDisplayLayer ensures things like -layout are properly forwarded to ASTableNode.
|
||||
+ (Class)layerClass
|
||||
@ -304,6 +308,11 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
ASDisplayNodeAssert(delegate == nil, @"ASTableView uses asyncDelegate, not UITableView's delegate property.");
|
||||
}
|
||||
|
||||
- (id<ASTableDataSource>)asyncDataSource
|
||||
{
|
||||
return _asyncDataSource;
|
||||
}
|
||||
|
||||
- (void)setAsyncDataSource:(id<ASTableDataSource>)asyncDataSource
|
||||
{
|
||||
// Changing super.dataSource will trigger a setNeedsLayout, so this must happen on the main thread.
|
||||
@ -346,6 +355,11 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
super.dataSource = (id<UITableViewDataSource>)_proxyDataSource;
|
||||
}
|
||||
|
||||
- (id<ASTableDelegate>)asyncDelegate
|
||||
{
|
||||
return _asyncDelegate;
|
||||
}
|
||||
|
||||
- (void)setAsyncDelegate:(id<ASTableDelegate>)asyncDelegate
|
||||
{
|
||||
// Changing super.delegate will trigger a setNeedsLayout, so this must happen on the main thread.
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
#import <AsyncDisplayKit/UIView+ASConvenience.h>
|
||||
#import <AsyncDisplayKit/UIImage+ASConvenience.h>
|
||||
#import <AsyncDisplayKit/NSArray+Diffing.h>
|
||||
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>
|
||||
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit+Debug.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Deprecated.h>
|
||||
|
||||
@ -10,78 +10,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
#import <AsyncDisplayKit/ASScrollDirection.h>
|
||||
|
||||
@class ASCollectionView;
|
||||
@protocol ASCollectionDataSource;
|
||||
@protocol ASCollectionDelegate;
|
||||
#include "ASCollectionViewLayoutInspector.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol ASCollectionViewLayoutInspecting <NSObject>
|
||||
|
||||
/**
|
||||
* Asks the inspector to provide a constrained size range for the given collection view node.
|
||||
*/
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
* Return the directions in which your collection view can scroll
|
||||
*/
|
||||
- (ASScrollDirection)scrollableDirections;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Asks the inspector to provide a constrained size range for the given supplementary node.
|
||||
*/
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
* Asks the inspector for the number of supplementary views for the given kind in the specified section.
|
||||
*/
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section;
|
||||
|
||||
/**
|
||||
* Allow the inspector to respond to delegate changes.
|
||||
*
|
||||
* @discussion A great time to update perform selector caches!
|
||||
*/
|
||||
- (void)didChangeCollectionViewDelegate:(nullable id<ASCollectionDelegate>)delegate;
|
||||
|
||||
/**
|
||||
* Allow the inspector to respond to dataSource changes.
|
||||
*
|
||||
* @discussion A great time to update perform selector caches!
|
||||
*/
|
||||
- (void)didChangeCollectionViewDataSource:(nullable id<ASCollectionDataSource>)dataSource;
|
||||
|
||||
#pragma mark Deprecated Methods
|
||||
|
||||
/**
|
||||
* Asks the inspector for the number of supplementary sections in the collection view for the given kind.
|
||||
*
|
||||
* @deprecated This method will not be called, and it is only deprecated as a reminder to remove it.
|
||||
* Supplementary elements must exist in the same sections as regular collection view items i.e. -numberOfSectionsInCollectionView:
|
||||
*/
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryNodeOfKind:(NSString *)kind ASDISPLAYNODE_DEPRECATED_MSG("Use ASCollectionNode's method instead.");
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* A layout inspector for non-flow layouts that returns a constrained size to let the cells layout itself as
|
||||
* far as possible based on the scrollable direction of the collection view. It throws exceptions for delegate
|
||||
* methods that are related to supplementary node's management.
|
||||
*/
|
||||
@interface ASCollectionViewLayoutInspector : NSObject <ASCollectionViewLayoutInspecting>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* A layout inspector implementation specific for the sizing behavior of UICollectionViewFlowLayouts
|
||||
*/
|
||||
|
||||
@ -16,90 +16,6 @@
|
||||
|
||||
#define kDefaultItemSize CGSizeMake(50, 50)
|
||||
|
||||
#pragma mark - Helper Functions
|
||||
|
||||
// Returns a constrained size to let the cells layout itself as far as possible based on the scrollable direction
|
||||
// of the collection view
|
||||
static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView) {
|
||||
CGSize maxSize = collectionView.bounds.size;
|
||||
if (ASScrollDirectionContainsHorizontalDirection(collectionView.scrollableDirections)) {
|
||||
maxSize.width = CGFLOAT_MAX;
|
||||
} else {
|
||||
maxSize.height = CGFLOAT_MAX;
|
||||
}
|
||||
return ASSizeRangeMake(CGSizeZero, maxSize);
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionViewLayoutInspector
|
||||
|
||||
@implementation ASCollectionViewLayoutInspector {
|
||||
struct {
|
||||
unsigned int implementsConstrainedSizeForNodeAtIndexPathDeprecated:1;
|
||||
unsigned int implementsConstrainedSizeForNodeAtIndexPath:1;
|
||||
} _delegateFlags;
|
||||
}
|
||||
|
||||
#pragma mark Lifecycle
|
||||
|
||||
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
[self didChangeCollectionViewDelegate:collectionView.asyncDelegate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark ASCollectionViewLayoutInspecting
|
||||
|
||||
- (void)didChangeCollectionViewDelegate:(id<ASCollectionDelegate>)delegate
|
||||
{
|
||||
if (delegate == nil) {
|
||||
memset(&_delegateFlags, 0, sizeof(_delegateFlags));
|
||||
} else {
|
||||
_delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
|
||||
_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionNode:constrainedSizeForItemAtIndexPath:)];
|
||||
}
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath) {
|
||||
return [collectionView.asyncDelegate collectionNode:collectionView.collectionNode constrainedSizeForItemAtIndexPath:indexPath];
|
||||
} else if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
return [collectionView.asyncDelegate collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath];
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
// With 2.0 `collectionView:constrainedSizeForNodeAtIndexPath:` was moved to the delegate. Assert if not implemented on the delegate but on the data source
|
||||
ASDisplayNodeAssert([collectionView.asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)] == NO, @"collectionView:constrainedSizeForNodeAtIndexPath: was moved from the ASCollectionDataSource to the ASCollectionDelegate.");
|
||||
}
|
||||
|
||||
return NodeConstrainedSizeForScrollDirection(collectionView);
|
||||
}
|
||||
|
||||
- (ASScrollDirection)scrollableDirections
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"layoutInspector object must implement -scrollableDirections %@", self);
|
||||
return ASScrollDirectionNone;
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
|
||||
return ASSizeRangeMake(CGSizeZero, CGSizeZero);
|
||||
}
|
||||
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ASCollectionViewFlowLayoutInspector
|
||||
|
||||
@interface ASCollectionViewFlowLayoutInspector ()
|
||||
|
||||
@ -60,7 +60,6 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
||||
|
||||
for (UICollectionViewLayoutAttributes *la in layoutAttributes) {
|
||||
//ASDisplayNodeAssert(![indexPathSet containsObject:la.indexPath], @"Shouldn't already contain indexPath");
|
||||
ASDisplayNodeAssert(la.representedElementCategory != UICollectionElementCategoryDecorationView, @"UICollectionView decoration views are not supported by ASCollectionView");
|
||||
[indexPathSet addObject:la.indexPath];
|
||||
}
|
||||
|
||||
|
||||
83
AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.h
Normal file
83
AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.h
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// ASCollectionViewLayoutInspector.h
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Garrett Moon on 11/19/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
#import <AsyncDisplayKit/ASScrollDirection.h>
|
||||
|
||||
@class ASCollectionView;
|
||||
@protocol ASCollectionDataSource;
|
||||
@protocol ASCollectionDelegate;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView);
|
||||
|
||||
@protocol ASCollectionViewLayoutInspecting <NSObject>
|
||||
|
||||
/**
|
||||
* Asks the inspector to provide a constrained size range for the given collection view node.
|
||||
*/
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
* Return the directions in which your collection view can scroll
|
||||
*/
|
||||
- (ASScrollDirection)scrollableDirections;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Asks the inspector to provide a constrained size range for the given supplementary node.
|
||||
*/
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
* Asks the inspector for the number of supplementary views for the given kind in the specified section.
|
||||
*/
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section;
|
||||
|
||||
/**
|
||||
* Allow the inspector to respond to delegate changes.
|
||||
*
|
||||
* @discussion A great time to update perform selector caches!
|
||||
*/
|
||||
- (void)didChangeCollectionViewDelegate:(nullable id<ASCollectionDelegate>)delegate;
|
||||
|
||||
/**
|
||||
* Allow the inspector to respond to dataSource changes.
|
||||
*
|
||||
* @discussion A great time to update perform selector caches!
|
||||
*/
|
||||
- (void)didChangeCollectionViewDataSource:(nullable id<ASCollectionDataSource>)dataSource;
|
||||
|
||||
#pragma mark Deprecated Methods
|
||||
|
||||
/**
|
||||
* Asks the inspector for the number of supplementary sections in the collection view for the given kind.
|
||||
*
|
||||
* @deprecated This method will not be called, and it is only deprecated as a reminder to remove it.
|
||||
* Supplementary elements must exist in the same sections as regular collection view items i.e. -numberOfSectionsInCollectionView:
|
||||
*/
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryNodeOfKind:(NSString *)kind ASDISPLAYNODE_DEPRECATED_MSG("Use ASCollectionNode's method instead.");
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* A layout inspector for non-flow layouts that returns a constrained size to let the cells layout itself as
|
||||
* far as possible based on the scrollable direction of the collection view. It throws exceptions for delegate
|
||||
* methods that are related to supplementary node's management.
|
||||
*/
|
||||
@interface ASCollectionViewLayoutInspector : NSObject <ASCollectionViewLayoutInspecting>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
94
AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.m
Normal file
94
AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.m
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// ASCollectionViewLayoutInspector.m
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Garrett Moon on 11/19/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ASCollectionViewLayoutInspector.h"
|
||||
|
||||
#import "ASCollectionView.h"
|
||||
#import "ASCollectionView+Undeprecated.h"
|
||||
|
||||
#pragma mark - Helper Functions
|
||||
|
||||
// Returns a constrained size to let the cells layout itself as far as possible based on the scrollable direction
|
||||
// of the collection view
|
||||
ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView) {
|
||||
CGSize maxSize = collectionView.bounds.size;
|
||||
if (ASScrollDirectionContainsHorizontalDirection(collectionView.scrollableDirections)) {
|
||||
maxSize.width = CGFLOAT_MAX;
|
||||
} else {
|
||||
maxSize.height = CGFLOAT_MAX;
|
||||
}
|
||||
return ASSizeRangeMake(CGSizeZero, maxSize);
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionViewLayoutInspector
|
||||
|
||||
@implementation ASCollectionViewLayoutInspector {
|
||||
struct {
|
||||
unsigned int implementsConstrainedSizeForNodeAtIndexPathDeprecated:1;
|
||||
unsigned int implementsConstrainedSizeForNodeAtIndexPath:1;
|
||||
} _delegateFlags;
|
||||
}
|
||||
|
||||
#pragma mark Lifecycle
|
||||
|
||||
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
[self didChangeCollectionViewDelegate:collectionView.asyncDelegate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark ASCollectionViewLayoutInspecting
|
||||
|
||||
- (void)didChangeCollectionViewDelegate:(id<ASCollectionDelegate>)delegate
|
||||
{
|
||||
if (delegate == nil) {
|
||||
memset(&_delegateFlags, 0, sizeof(_delegateFlags));
|
||||
} else {
|
||||
_delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
|
||||
_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionNode:constrainedSizeForItemAtIndexPath:)];
|
||||
}
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath) {
|
||||
return [collectionView.asyncDelegate collectionNode:collectionView.collectionNode constrainedSizeForItemAtIndexPath:indexPath];
|
||||
} else if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
return [collectionView.asyncDelegate collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath];
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
// With 2.0 `collectionView:constrainedSizeForNodeAtIndexPath:` was moved to the delegate. Assert if not implemented on the delegate but on the data source
|
||||
ASDisplayNodeAssert([collectionView.asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)] == NO, @"collectionView:constrainedSizeForNodeAtIndexPath: was moved from the ASCollectionDataSource to the ASCollectionDelegate.");
|
||||
}
|
||||
|
||||
return NodeConstrainedSizeForScrollDirection(collectionView);
|
||||
}
|
||||
|
||||
- (ASScrollDirection)scrollableDirections
|
||||
{
|
||||
return ASScrollDirectionNone;
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
|
||||
return ASSizeRangeMake(CGSizeZero, CGSizeZero);
|
||||
}
|
||||
|
||||
- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -22,8 +22,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ASEventLog : NSObject
|
||||
|
||||
/**
|
||||
* Create a new event log.
|
||||
*
|
||||
* @param anObject The object whose events we are logging. This object is not retained.
|
||||
*/
|
||||
- (instancetype)initWithObject:(id)anObject;
|
||||
|
||||
- (void)logEventWithBacktrace:(nullable NSArray<NSString *> *)backtrace format:(NSString *)format, ... NS_FORMAT_FUNCTION(2, 3);
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -13,57 +13,86 @@
|
||||
#import "ASEventLog.h"
|
||||
#import "ASThread.h"
|
||||
#import "ASTraceEvent.h"
|
||||
#import "ASObjectDescriptionHelpers.h"
|
||||
|
||||
@interface ASEventLog ()
|
||||
{
|
||||
@implementation 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;
|
||||
|
||||
// A description of the object we're logging for. This is immutable.
|
||||
NSString *_objectDescription;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ASEventLog
|
||||
/**
|
||||
* Even just when debugging, all these events can take up considerable memory.
|
||||
* Store them in a shared NSCache to limit the total consumption.
|
||||
*/
|
||||
+ (NSCache<ASEventLog *, NSMutableArray<ASTraceEvent *> *> *)contentsCache
|
||||
{
|
||||
static NSCache *cache;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
cache = [[NSCache alloc] init];
|
||||
});
|
||||
return cache;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
- (instancetype)initWithObject:(id)anObject
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_objectDescription = ASObjectDescriptionMakeTiny(anObject);
|
||||
_eventLogHead = -1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
// This method is marked unavailable so the compiler won't let them call it.
|
||||
ASDisplayNodeFailAssert(@"Failed to call initWithObject:");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)logEventWithBacktrace:(NSArray<NSString *> *)backtrace format:(NSString *)format, ...
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
ASTraceEvent *event = [[ASTraceEvent alloc] initWithObject:self
|
||||
backtrace:backtrace
|
||||
ASTraceEvent *event = [[ASTraceEvent alloc] initWithBacktrace: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];
|
||||
NSCache *cache = [ASEventLog contentsCache];
|
||||
NSMutableArray<ASTraceEvent *> *events = [cache objectForKey:self];
|
||||
if (events == nil) {
|
||||
events = [NSMutableArray arrayWithObject:event];
|
||||
[cache setObject:events forKey:self];
|
||||
_eventLogHead = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment the head index.
|
||||
_eventLogHead = (_eventLogHead + 1) % ASEVENTLOG_CAPACITY;
|
||||
if (_eventLogHead < _eventLog.count) {
|
||||
[_eventLog replaceObjectAtIndex:_eventLogHead withObject:event];
|
||||
if (_eventLogHead < events.count) {
|
||||
[events replaceObjectAtIndex:_eventLogHead withObject:event];
|
||||
} else {
|
||||
[_eventLog insertObject:event atIndex:_eventLogHead];
|
||||
[events insertObject:event atIndex:_eventLogHead];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<ASTraceEvent *> *)eventLog
|
||||
- (NSArray<ASTraceEvent *> *)events
|
||||
{
|
||||
NSMutableArray<ASTraceEvent *> *events = [[ASEventLog contentsCache] objectForKey:self];
|
||||
if (events == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
NSUInteger tail = (_eventLogHead + 1);
|
||||
NSUInteger count = _eventLog.count;
|
||||
NSUInteger count = events.count;
|
||||
|
||||
NSMutableArray<ASTraceEvent *> *result = [NSMutableArray array];
|
||||
|
||||
@ -71,10 +100,25 @@
|
||||
for (NSUInteger actualIndex = 0; actualIndex < ASEVENTLOG_CAPACITY; actualIndex++) {
|
||||
NSInteger ringIndex = (tail + actualIndex) % ASEVENTLOG_CAPACITY;
|
||||
if (ringIndex < count) {
|
||||
[result addObject:_eventLog[ringIndex]];
|
||||
[result addObject:events[ringIndex]];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
/**
|
||||
* This description intentionally doesn't follow the standard description format.
|
||||
* Since this is a log, it's important for the description to look a certain way, and
|
||||
* the formal description style doesn't allow for newlines and has a ton of punctuation.
|
||||
*/
|
||||
NSArray *events = [self events];
|
||||
if (events == nil) {
|
||||
return [NSString stringWithFormat:@"Event log for %@ was purged to conserve memory.", _objectDescription];
|
||||
} else {
|
||||
return [NSString stringWithFormat:@"Event log for %@. Events: %@", _objectDescription, events];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -15,10 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* This method is dealloc safe.
|
||||
*/
|
||||
- (instancetype)initWithObject:(id)object
|
||||
backtrace:(nullable NSArray<NSString *> *)backtrace
|
||||
- (instancetype)initWithBacktrace:(nullable NSArray<NSString *> *)backtrace
|
||||
format:(NSString *)format
|
||||
arguments:(va_list)arguments NS_FORMAT_FUNCTION(3,0);
|
||||
arguments:(va_list)arguments NS_FORMAT_FUNCTION(2,0);
|
||||
|
||||
// Will be nil unless AS_SAVE_EVENT_BACKTRACES=1 (default=0)
|
||||
@property (nonatomic, nullable, readonly) NSArray<NSString *> *backtrace;
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
#import "ASTraceEvent.h"
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import "ASObjectDescriptionHelpers.h"
|
||||
|
||||
static NSString *const ASTraceEventThreadDescriptionKey = @"ASThreadTraceEventDescription";
|
||||
|
||||
@interface ASTraceEvent ()
|
||||
@property (nonatomic, strong, readonly) NSString *objectDescription;
|
||||
@ -17,7 +18,7 @@
|
||||
|
||||
@implementation ASTraceEvent
|
||||
|
||||
- (instancetype)initWithObject:(id)object backtrace:(NSArray<NSString *> *)backtrace format:(NSString *)format arguments:(va_list)args
|
||||
- (instancetype)initWithBacktrace:(NSArray<NSString *> *)backtrace format:(NSString *)format arguments:(va_list)args
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
@ -30,18 +31,23 @@
|
||||
// Create the format string passed to us.
|
||||
_message = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
|
||||
_objectDescription = ASObjectDescriptionMakeTiny(object);
|
||||
|
||||
NSThread *thread = [NSThread currentThread];
|
||||
NSString *threadDescription = thread.name;
|
||||
if (threadDescription.length == 0) {
|
||||
if ([thread isMainThread]) {
|
||||
threadDescription = @"Main";
|
||||
} else {
|
||||
// If the bg thread has no name, we cache a 4-character ptr string to identify it by
|
||||
// inside the thread dictionary.
|
||||
NSMutableDictionary *threadDict = thread.threadDictionary;
|
||||
threadDescription = threadDict[ASTraceEventThreadDescriptionKey];
|
||||
if (threadDescription == nil) {
|
||||
// Want these to be 4-chars to line up with "Main". It's possible that a collision could happen
|
||||
// here but it's so unbelievably likely to impact development, the risk is acceptable.
|
||||
NSString *ptrString = [NSString stringWithFormat:@"%p", thread];
|
||||
threadDescription = [ptrString substringFromIndex:MAX(0, ptrString.length - 4)];
|
||||
threadDict[ASTraceEventThreadDescriptionKey] = threadDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
_threadDescription = threadDescription;
|
||||
@ -54,7 +60,7 @@
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@ (%@) t=%7.3f: %@>", _objectDescription, _threadDescription, _timestamp, _message];
|
||||
return [NSString stringWithFormat:@"<(%@) t=%7.3f: %@>", _threadDescription, _timestamp, _message];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -19,6 +19,24 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface ASCollectionView (Undeprecated)
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous delegate of the collection view
|
||||
*
|
||||
* @discussion The delegate must adopt the ASCollectionDelegate protocol. The collection view maintains a weak reference to the delegate object.
|
||||
*
|
||||
* The delegate object is responsible for providing size constraints for nodes and indicating whether batch fetching should begin.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCollectionDelegate> asyncDelegate;
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous data source of the collection view
|
||||
*
|
||||
* @discussion The datasource must adopt the ASCollectionDataSource protocol. The collection view maintains a weak reference to the datasource object.
|
||||
*
|
||||
* The datasource object is responsible for providing nodes or node creation blocks to the collection view.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCollectionDataSource> asyncDataSource;
|
||||
|
||||
/**
|
||||
* Initializes an ASCollectionView
|
||||
*
|
||||
|
||||
@ -19,6 +19,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface ASTableView (Undeprecated)
|
||||
|
||||
@property (nonatomic, weak) id<ASTableDelegate> asyncDelegate;
|
||||
@property (nonatomic, weak) id<ASTableDataSource> asyncDataSource;
|
||||
|
||||
/**
|
||||
* Initializer.
|
||||
*
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#import "ASCollectionNode.h"
|
||||
#import "ASCollectionViewFlowLayoutInspector.h"
|
||||
#import "ASCellNode.h"
|
||||
#import "ASCollectionView+Undeprecated.h"
|
||||
|
||||
@interface ASCollectionView (Private)
|
||||
|
||||
|
||||
@ -111,12 +111,6 @@
|
||||
};
|
||||
|
||||
XCTAssertThrows([node layoutThatFits:ASSizeRangeMake(CGSizeMake(0, FLT_MAX))]);
|
||||
|
||||
// This dance is necessary as we would assert in case we create an ASDimension that is not real numbers
|
||||
ASDimension width = displayNode.style.width;
|
||||
width.value = INFINITY;
|
||||
displayNode.style.width = width;
|
||||
XCTAssertThrows([node layoutThatFits:ASSizeRangeMake(CGSizeMake(0, 0), CGSizeMake(INFINITY, INFINITY))]);
|
||||
}
|
||||
|
||||
- (void)testThatLayoutCreatedWithInvalidSizeCausesException
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
- (instancetype)__initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||
{
|
||||
|
||||
return [super _initWithFrame:frame style:style dataControllerClass:[ASTestDataController class] eventLog:[[ASEventLog alloc] init]];
|
||||
return [super _initWithFrame:frame style:style dataControllerClass:[ASTestDataController class] eventLog:nil];
|
||||
}
|
||||
|
||||
- (ASTestDataController *)testDataController
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user