Fix the Initialization Hierarchy (#3207)

* Fix the initializers setup

* Update Swift example

* Remove incorrect comment

* Add one to ASTableNode
This commit is contained in:
Adlai Holler 2017-03-28 11:48:20 -07:00 committed by GitHub
parent 27c94069ae
commit fcbbea51a6
10 changed files with 84 additions and 88 deletions

View File

@ -29,6 +29,8 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@interface ASCollectionNode : ASDisplayNode <ASRangeControllerUpdateRangeProtocol> @interface ASCollectionNode : ASDisplayNode <ASRangeControllerUpdateRangeProtocol>
- (instancetype)init NS_UNAVAILABLE;
/** /**
* Initializes an ASCollectionNode * Initializes an ASCollectionNode
* *

View File

@ -123,14 +123,6 @@
} }
} }
- (instancetype)init
{
ASDISPLAYNODE_NOT_DESIGNATED_INITIALIZER();
UICollectionViewLayout *nilLayout = nil;
self = [self initWithCollectionViewLayout:nilLayout]; // Will throw an exception for lacking a UICV Layout.
return nil;
}
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
{ {
return [self initWithFrame:CGRectZero collectionViewLayout:layout layoutFacilitator:nil]; return [self initWithFrame:CGRectZero collectionViewLayout:layout layoutFacilitator:nil];
@ -143,17 +135,14 @@
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator
{ {
__weak __typeof__(self) weakSelf = self; if (self = [super init]) {
ASDisplayNodeViewBlock collectionViewBlock = ^UIView *{ __weak __typeof__(self) weakSelf = self;
// Variable will be unused if event logging is off. [self setViewBlock:^{
__unused __typeof__(self) strongSelf = weakSelf; __typeof__(self) strongSelf = weakSelf;
return [[[strongSelf collectionViewClass] alloc] _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:layoutFacilitator eventLog:ASDisplayNodeGetEventLog(strongSelf)]; return [[[strongSelf collectionViewClass] alloc] _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:layoutFacilitator eventLog:ASDisplayNodeGetEventLog(strongSelf)];
}; }];
if (self = [super initWithViewBlock:collectionViewBlock didLoadBlock:nil]) {
return self;
} }
return nil; return self;
} }
#pragma mark ASDisplayNode #pragma mark ASDisplayNode

View File

@ -125,7 +125,7 @@ extern NSInteger const ASDefaultDrawingPriority;
* @return An ASDisplayNode instance whose view will be a subclass that enables asynchronous rendering, and passes * @return An ASDisplayNode instance whose view will be a subclass that enables asynchronous rendering, and passes
* through -layout and touch handling methods. * through -layout and touch handling methods.
*/ */
- (instancetype)init; - (instancetype)init NS_DESIGNATED_INITIALIZER;
/** /**
@ -183,6 +183,28 @@ extern NSInteger const ASDefaultDrawingPriority;
*/ */
- (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body; - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body;
/**
* Set the block that should be used to load this node's view.
*
* @param viewBlock The block that creates a view for this node.
*
* @precondition The node is not yet loaded.
*
* @note You will usually NOT call this. See the limitations documented in @c initWithViewBlock:
*/
- (void)setViewBlock:(ASDisplayNodeViewBlock)viewBlock;
/**
* Set the block that should be used to load this node's layer.
*
* @param viewBlock The block that creates a layer for this node.
*
* @precondition The node is not yet loaded.
*
* @note You will usually NOT call this. See the limitations documented in @c initWithLayerBlock:
*/
- (void)setLayerBlock:(ASDisplayNodeLayerBlock)layerBlock;
/** /**
* @abstract Returns whether the node is synchronous. * @abstract Returns whether the node is synchronous.
* *

View File

@ -316,12 +316,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (instancetype)initWithViewClass:(Class)viewClass - (instancetype)initWithViewClass:(Class)viewClass
{ {
if (!(self = [super init])) if (!(self = [self init]))
return nil; return nil;
ASDisplayNodeAssert([viewClass isSubclassOfClass:[UIView class]], @"should initialize with a subclass of UIView"); ASDisplayNodeAssert([viewClass isSubclassOfClass:[UIView class]], @"should initialize with a subclass of UIView");
[self _initializeInstance];
_viewClass = viewClass; _viewClass = viewClass;
_flags.synchronous = ![viewClass isSubclassOfClass:[_ASDisplayView class]]; _flags.synchronous = ![viewClass isSubclassOfClass:[_ASDisplayView class]];
@ -330,13 +329,12 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (instancetype)initWithLayerClass:(Class)layerClass - (instancetype)initWithLayerClass:(Class)layerClass
{ {
if (!(self = [super init])) { if (!(self = [self init])) {
return nil; return nil;
} }
ASDisplayNodeAssert([layerClass isSubclassOfClass:[CALayer class]], @"should initialize with a subclass of CALayer"); ASDisplayNodeAssert([layerClass isSubclassOfClass:[CALayer class]], @"should initialize with a subclass of CALayer");
[self _initializeInstance];
_layerClass = layerClass; _layerClass = layerClass;
_flags.synchronous = ![layerClass isSubclassOfClass:[_ASDisplayLayer class]]; _flags.synchronous = ![layerClass isSubclassOfClass:[_ASDisplayLayer class]];
_flags.layerBacked = YES; _flags.layerBacked = YES;
@ -346,26 +344,18 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock - (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock
{ {
return [self _initWithViewBlock:viewBlock didLoadBlock:nil]; return [self initWithViewBlock:viewBlock didLoadBlock:nil];
}
- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock
{
return [self _initWithViewBlock:viewBlock didLoadBlock:didLoadBlock];
} }
- (instancetype)_initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock - (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock
{ {
if (!(self = [super init])) { if (!(self = [self init])) {
return nil; return nil;
} }
ASDisplayNodeAssertNotNil(viewBlock, @"should initialize with a valid block that returns a UIView"); [self setViewBlock:viewBlock];
[self _initializeInstance];
_viewBlock = viewBlock;
_flags.synchronous = YES;
if (didLoadBlock != nil) { if (didLoadBlock != nil) {
_onDidLoadBlocks = [NSMutableArray arrayWithObject:didLoadBlock]; [self onDidLoad:didLoadBlock];
} }
return self; return self;
@ -373,33 +363,42 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock - (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock
{ {
return [self _initWithLayerBlock:layerBlock didLoadBlock:nil]; return [self initWithLayerBlock:layerBlock didLoadBlock:nil];
} }
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock - (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock
{ {
return [self _initWithLayerBlock:layerBlock didLoadBlock:didLoadBlock]; if (!(self = [self init])) {
}
- (instancetype)_initWithLayerBlock:(ASDisplayNodeLayerBlock)layerBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock
{
if (!(self = [super init])) {
return nil; return nil;
} }
ASDisplayNodeAssertNotNil(layerBlock, @"should initialize with a valid block that returns a CALayer"); [self setLayerBlock:layerBlock];
[self _initializeInstance];
_layerBlock = layerBlock;
_flags.synchronous = YES;
_flags.layerBacked = YES;
if (didLoadBlock != nil) { if (didLoadBlock != nil) {
_onDidLoadBlocks = [NSMutableArray arrayWithObject:didLoadBlock]; [self onDidLoad:didLoadBlock];
} }
return self; return self;
} }
- (void)setViewBlock:(ASDisplayNodeViewBlock)viewBlock
{
ASDisplayNodeAssertFalse(self.nodeLoaded);
ASDisplayNodeAssertNotNil(viewBlock, @"should initialize with a valid block that returns a UIView");
_viewBlock = viewBlock;
_flags.synchronous = YES;
}
- (void)setLayerBlock:(ASDisplayNodeLayerBlock)layerBlock
{
ASDisplayNodeAssertFalse(self.nodeLoaded);
ASDisplayNodeAssertNotNil(layerBlock, @"should initialize with a valid block that returns a CALayer");
_layerBlock = layerBlock;
_flags.synchronous = YES;
_flags.layerBacked = YES;
}
- (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body - (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body
{ {
ASDN::MutexLocker l(__instanceLock__); ASDN::MutexLocker l(__instanceLock__);

View File

@ -64,7 +64,10 @@
- (instancetype)init - (instancetype)init
{ {
return [super initWithViewBlock:^UIView *{ return [[ASScrollView alloc] init]; }]; if (self = [super init]) {
[self setViewBlock:^UIView *{ return [[ASScrollView alloc] init]; }];
}
return self;
} }
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize

View File

@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface ASTableNode : ASDisplayNode <ASRangeControllerUpdateRangeProtocol> @interface ASTableNode : ASDisplayNode <ASRangeControllerUpdateRangeProtocol>
- (instancetype)init; // UITableViewStylePlain - (instancetype)init; // UITableViewStylePlain
- (instancetype)initWithStyle:(UITableViewStyle)style; - (instancetype)initWithStyle:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER;
@property (strong, nonatomic, readonly) ASTableView *view; @property (strong, nonatomic, readonly) ASTableView *view;

View File

@ -72,40 +72,22 @@
#pragma mark Lifecycle #pragma mark Lifecycle
- (instancetype)_initWithTableView:(ASTableView *)tableView
{
// Avoid a retain cycle. In this case, the ASTableView is creating us, and strongly retains us.
ASTableView * __weak weakTableView = tableView;
if (self = [super initWithViewBlock:^UIView *{ return weakTableView; }]) {
__unused __weak ASTableView *view = [self view];
return self;
}
return nil;
}
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass
{
__weak __typeof__(self) weakSelf = self;
ASDisplayNodeViewBlock tableViewBlock = ^UIView *{
// Variable will be unused if event logging is off.
__unused __typeof__(self) strongSelf = weakSelf;
return [[ASTableView alloc] _initWithFrame:frame style:style dataControllerClass:dataControllerClass eventLog:ASDisplayNodeGetEventLog(strongSelf)];
};
if (self = [super initWithViewBlock:tableViewBlock]) {
return self;
}
return nil;
}
- (instancetype)initWithStyle:(UITableViewStyle)style - (instancetype)initWithStyle:(UITableViewStyle)style
{ {
return [self _initWithFrame:CGRectZero style:style dataControllerClass:nil]; if (self = [super init]) {
__weak __typeof__(self) weakSelf = self;
[self setViewBlock:^{
// Variable will be unused if event logging is off.
__unused __typeof__(self) strongSelf = weakSelf;
return [[ASTableView alloc] _initWithFrame:CGRectZero style:style dataControllerClass:nil eventLog:ASDisplayNodeGetEventLog(strongSelf)];
}];
}
return self;
} }
- (instancetype)init - (instancetype)init
{ {
return [self _initWithFrame:CGRectZero style:UITableViewStylePlain dataControllerClass:nil]; return [self initWithStyle:UITableViewStylePlain];
} }
#pragma mark ASDisplayNode #pragma mark ASDisplayNode

View File

@ -121,10 +121,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
#pragma mark - #pragma mark -
#pragma mark ASTableView #pragma mark ASTableView
@interface ASTableNode ()
- (instancetype)_initWithTableView:(ASTableView *)tableView;
@end
@interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASDataControllerEnvironmentDelegate> @interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASDataControllerEnvironmentDelegate>
{ {
ASTableViewProxy *_proxyDataSource; ASTableViewProxy *_proxyDataSource;

View File

@ -240,10 +240,10 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
- (void)displayImmediately; - (void)displayImmediately;
/// Alternative initialiser for backing with a custom view class. Supports asynchronous display with _ASDisplayView subclasses. /// Alternative initialiser for backing with a custom view class. Supports asynchronous display with _ASDisplayView subclasses.
- (nullable instancetype)initWithViewClass:(Class)viewClass; - (instancetype)initWithViewClass:(Class)viewClass;
/// Alternative initialiser for backing with a custom layer class. Supports asynchronous display with _ASDisplayLayer subclasses. /// Alternative initialiser for backing with a custom layer class. Supports asynchronous display with _ASDisplayLayer subclasses.
- (nullable instancetype)initWithLayerClass:(Class)layerClass; - (instancetype)initWithLayerClass:(Class)layerClass;
@property (nonatomic, assign) CGFloat contentsScaleForDisplay; @property (nonatomic, assign) CGFloat contentsScaleForDisplay;

View File

@ -55,7 +55,10 @@ final class SpinnerNode: ASDisplayNode {
} }
override init() { override init() {
super.init(viewBlock: { UIActivityIndicatorView(activityIndicatorStyle: .Gray) }, didLoadBlock: nil) super.init()
setViewBlock {
UIActivityIndicatorView(activityIndicatorStyle: .Gray)
}
// Set spinner node to default size of the activitiy indicator view // Set spinner node to default size of the activitiy indicator view
self.style.preferredSize = CGSizeMake(20.0, 20.0) self.style.preferredSize = CGSizeMake(20.0, 20.0)