mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Remove unused methods.
`-[ASDisplayNode addSubnodeAsynchronously::]` and `-replaceSubnodeAsynchronously:::` are unused and confusingly increase AsyncDisplayKit's API surface. `-addSubnode:` and friends are thread-safe and can be used on background threads, so removing these methods does not constitute a decrease in functionality.
This commit is contained in:
@@ -221,32 +221,6 @@
|
||||
*/
|
||||
- (void)replaceSubnode:(ASDisplayNode *)subnode withSubnode:(ASDisplayNode *)replacementSubnode;
|
||||
|
||||
/**
|
||||
* @abstract Add a subnode, but have it size asynchronously on a background queue.
|
||||
*
|
||||
* @param subnode The unsized subnode to insert into the view hierarchy
|
||||
* @param completion The completion callback will be called on the main queue after the subnode has been inserted in
|
||||
* place of the placeholder.
|
||||
*
|
||||
* @return A placeholder node is inserted into the hierarchy where the node will be. The placeholder can be moved around
|
||||
* in the hiercharchy while the view is sizing. Once sizing is complete on the background queue, this placeholder will
|
||||
* be removed and the replacement will be put at its place.
|
||||
*/
|
||||
- (ASDisplayNode *)addSubnodeAsynchronously:(ASDisplayNode *)subnode
|
||||
completion:(void(^)(ASDisplayNode *replacement))completion;
|
||||
|
||||
/**
|
||||
* @abstract Replace a subnode, but have it size asynchronously on a background queue.
|
||||
*
|
||||
* @param subnode A subnode of self.
|
||||
* @param replacementSubnode A node with which to replace subnode.
|
||||
* @param completion The completion callback will be called on the main queue after the replacementSubnode has replaced
|
||||
* subnode.
|
||||
*/
|
||||
- (void)replaceSubnodeAsynchronously:(ASDisplayNode *)subnode
|
||||
withNode:(ASDisplayNode *)replacementSubnode
|
||||
completion:(void(^)(BOOL cancelled, ASDisplayNode *replacement, ASDisplayNode *oldSubnode))completion;
|
||||
|
||||
/**
|
||||
* @abstract Remove this node from its supernode.
|
||||
*
|
||||
|
||||
@@ -1401,91 +1401,6 @@ static void _recursiveSetPreventOrCancelDisplay(ASDisplayNode *node, CALayer *la
|
||||
|
||||
}
|
||||
|
||||
- (void)replaceSubnodeAsynchronously:(ASDisplayNode *)old withNode:(ASDisplayNode *)replacement completion:(void(^)(BOOL cancelled, ASDisplayNode *replacement, ASDisplayNode *oldSubnode))completion
|
||||
{
|
||||
|
||||
ASDisplayNodeAssert(old.supernode == self, @"Must replace something that is actually a subnode. You passed: %@", old);
|
||||
ASDisplayNodeAssert(!replacement.nodeLoaded, @"Can't async size something that already has a view, since we currently have no way to convert a viewed node into a viewless one...");
|
||||
|
||||
// If we're already marked for replacement, cancel the pending request
|
||||
ASSentinel *sentinel = [old _asyncReplaceSentinel];
|
||||
uint32_t sentinelValue = [sentinel increment];
|
||||
|
||||
// Enqueue async sizing on our argument
|
||||
[replacement _enqueueAsyncSizingWithSentinel:sentinel completion:^(ASDisplayNode *replacementCompletedNode) {
|
||||
// Sizing is done; swap with our other view
|
||||
// Check sentinel one more time in case it changed during sizing
|
||||
if (replacementCompletedNode && sentinel.value == sentinelValue) {
|
||||
if (old.supernode) {
|
||||
if (old.supernode.inWindow) {
|
||||
// Now wait for async display before notifying delegate that replacement is complete
|
||||
|
||||
// When async sizing is complete, add subnode below placeholder with 0 alpha
|
||||
CGFloat replacementAlpha = replacement.alpha;
|
||||
BOOL wasAsyncTransactionContainer = replacement.asyncdisplaykit_asyncTransactionContainer;
|
||||
[old.supernode insertSubnode:replacement belowSubnode:old];
|
||||
|
||||
replacementCompletedNode.alpha = 0.0;
|
||||
replacementCompletedNode.asyncdisplaykit_asyncTransactionContainer = YES;
|
||||
|
||||
ASDisplayNodeCAssert(replacementCompletedNode.nodeLoaded, @".layer shouldn't be the thing to load the view");
|
||||
|
||||
[replacement.layer.asyncdisplaykit_asyncTransaction addCompletionBlock:^(id<NSObject> unused, BOOL canceled) {
|
||||
ASDisplayNodeCAssertMainThread();
|
||||
|
||||
canceled |= (sentinel.value != sentinelValue);
|
||||
|
||||
replacementCompletedNode.alpha = replacementAlpha;
|
||||
replacementCompletedNode.asyncdisplaykit_asyncTransactionContainer = wasAsyncTransactionContainer;
|
||||
|
||||
if (!canceled) {
|
||||
[old removeFromSupernode];
|
||||
} else {
|
||||
[replacementCompletedNode removeFromSupernode];
|
||||
}
|
||||
|
||||
completion(canceled, replacementCompletedNode, old);
|
||||
}];
|
||||
} else {
|
||||
// Not in window, don't wait for async display
|
||||
[old.supernode replaceSubnode:old withSubnode:replacement];
|
||||
completion(NO, replacementCompletedNode, old);
|
||||
}
|
||||
|
||||
} else { // Old has been moved no longer to be in the hierarchy
|
||||
// TODO: add code to removeFromSupernode and hook UIView methods to cancel sentinel here?
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Tried to replaceSubnodeAsynchronously an ASDisplayNode, but then removed it from the hierarchy... what did you mean?" userInfo:nil];
|
||||
|
||||
completion(NO, replacementCompletedNode, old);
|
||||
}
|
||||
} else { // If we were cancelled
|
||||
completion(YES, nil, nil);
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (ASDisplayNode *)addSubnodeAsynchronously:(ASDisplayNode *)replacement completion:(void(^)(ASDisplayNode *fullySizedSubnode))completion
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
|
||||
// Create a placeholder ASDisplayNode that saves this guy's place in the view hierarchy for when things return later
|
||||
ASDisplayNode *placeholder = [[ASDisplayNode alloc] init];
|
||||
|
||||
[self addSubnode:placeholder];
|
||||
[self replaceSubnodeAsynchronously:placeholder withNode:replacement completion:^(BOOL cancelled, ASDisplayNode *replacementBlock, ASDisplayNode *placeholderBlock) {
|
||||
if (replacementBlock && placeholderBlock && !cancelled) {
|
||||
[placeholderBlock removeFromSupernode];
|
||||
completion(replacementBlock);
|
||||
} else {
|
||||
[placeholderBlock removeFromSupernode];
|
||||
}
|
||||
}];
|
||||
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASDisplayNode (Debugging)
|
||||
|
||||
@@ -914,167 +914,6 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
|
||||
[d release];
|
||||
}
|
||||
|
||||
- (void)testAddSubnodeAsync
|
||||
{
|
||||
|
||||
ASTestDisplayNode *parent = [[ASTestDisplayNode alloc] init];
|
||||
|
||||
__block BOOL calculateSizeCalled = NO;
|
||||
__block CGSize passedInSize;
|
||||
__block BOOL sizeCalculatedOnMainThread;
|
||||
ASTestDisplayNode *nodeToAddAsync = [[ASTestDisplayNode alloc] init];
|
||||
nodeToAddAsync.bounds = CGRectMake(100, 40, 42, 56);
|
||||
nodeToAddAsync.calculateSizeBlock = ^(ASDisplayNode *n, CGSize size){
|
||||
calculateSizeCalled = YES;
|
||||
passedInSize = size;
|
||||
sizeCalculatedOnMainThread = [NSThread isMainThread];
|
||||
return CGSizeZero;
|
||||
};
|
||||
|
||||
dispatch_suspend([ASDisplayNode asyncSizingQueue]);
|
||||
|
||||
__block BOOL completed = NO;
|
||||
ASDisplayNode *placeholder = [parent addSubnodeAsynchronously:nodeToAddAsync completion:^(ASDisplayNode *replacement) {
|
||||
completed = YES;
|
||||
}];
|
||||
|
||||
// Check it hasn't been added yet
|
||||
XCTAssertTrue(placeholder.supernode == parent, @"didn't make a placeholder");
|
||||
XCTAssertTrue(nodeToAddAsync.supernode == nil, @"oops, added node too soon");
|
||||
XCTAssertFalse(calculateSizeCalled, @"too soon to calculate size!");
|
||||
|
||||
dispatch_resume([ASDisplayNode asyncSizingQueue]);
|
||||
|
||||
// Let the block execute on the bg thread
|
||||
XCTAssertTrue(ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{ return completed; }), @"Didn't finish the test fast enough");
|
||||
|
||||
XCTAssertTrue(placeholder.supernode == nil, @"didn't remove the placeholder");
|
||||
XCTAssertTrue(nodeToAddAsync.supernode == parent, @"oops, didn't add the node");
|
||||
XCTAssertTrue(calculateSizeCalled, @"too soon to calculate size!");
|
||||
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(42, 56), passedInSize), @"Should pass in initial bounds size");
|
||||
XCTAssertFalse(sizeCalculatedOnMainThread, @"Should pass in initial bounds size");
|
||||
|
||||
[parent release];
|
||||
[nodeToAddAsync release];
|
||||
}
|
||||
|
||||
- (void)testReplaceSubnodeAsync
|
||||
{
|
||||
ASTestDisplayNode *parent = [[ASTestDisplayNode alloc] init];
|
||||
|
||||
__block BOOL calculateSizeCalled = NO;
|
||||
__block CGSize passedInSize;
|
||||
__block BOOL sizeCalculatedOnMainThread;
|
||||
ASTestDisplayNode *nodeToAddAsync = [[ASTestDisplayNode alloc] init];
|
||||
nodeToAddAsync.bounds = CGRectMake(100, 40, 42, 56);
|
||||
nodeToAddAsync.calculateSizeBlock = ^(ASDisplayNode *n, CGSize size){
|
||||
calculateSizeCalled = YES;
|
||||
passedInSize = size;
|
||||
sizeCalculatedOnMainThread = [NSThread isMainThread];
|
||||
return CGSizeZero;
|
||||
};
|
||||
|
||||
ASDisplayNode *replaceMe = [[ASDisplayNode alloc] init];
|
||||
[parent addSubnode:replaceMe];
|
||||
|
||||
dispatch_suspend([ASDisplayNode asyncSizingQueue]);
|
||||
|
||||
__block BOOL completed = NO;
|
||||
|
||||
[parent replaceSubnodeAsynchronously:replaceMe withNode:nodeToAddAsync completion:^(BOOL cancelled, ASDisplayNode *nodeToAddAsyncBlockArgument, ASDisplayNode *replaceMeBlockArgument) {
|
||||
XCTAssertTrue(nodeToAddAsyncBlockArgument == nodeToAddAsync, @"Passed in wrong node for the replacing node");
|
||||
XCTAssertTrue(replaceMeBlockArgument == replaceMe, @"Passed in wrong node for the replaced node");
|
||||
completed = YES;
|
||||
}];
|
||||
|
||||
// Check it hasn't been replaced yet
|
||||
XCTAssertTrue(replaceMe.supernode == parent, @"removed too soon!");
|
||||
XCTAssertTrue(nodeToAddAsync.supernode == nil, @"oops, added node too soon");
|
||||
XCTAssertFalse(calculateSizeCalled, @"too soon to calculate size!");
|
||||
|
||||
dispatch_resume([ASDisplayNode asyncSizingQueue]);
|
||||
|
||||
// Let the block execute on the bg thread
|
||||
XCTAssertTrue(ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{ return completed; }), @"Didn't finish the test fast enough");
|
||||
|
||||
XCTAssertTrue(replaceMe.supernode == nil, @"didn't remove old node");
|
||||
XCTAssertTrue(nodeToAddAsync.supernode == parent, @"oops, added node too soon");
|
||||
XCTAssertTrue(calculateSizeCalled, @"too soon to calculate size!");
|
||||
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(42, 56), passedInSize), @"Should pass in initial bounds size");
|
||||
XCTAssertFalse(sizeCalculatedOnMainThread, @"Should pass in initial bounds size");
|
||||
|
||||
[parent release];
|
||||
[nodeToAddAsync release];
|
||||
}
|
||||
|
||||
- (void)testCancelReplaceSubnodeAsyncByReplacingAgain
|
||||
{
|
||||
|
||||
ASTestDisplayNode *parent = [[ASTestDisplayNode alloc] init];
|
||||
|
||||
dispatch_semaphore_t allowFirst = dispatch_semaphore_create(0);
|
||||
ASTestDisplayNode *first = [[ASTestDisplayNode alloc] init];
|
||||
first.bounds = CGRectMake(100, 40, 42, 56);
|
||||
first.calculateSizeBlock = ^(ASDisplayNode *n, CGSize size){
|
||||
dispatch_semaphore_wait(allowFirst, DISPATCH_TIME_FOREVER);
|
||||
return CGSizeZero;
|
||||
};
|
||||
|
||||
dispatch_semaphore_t allowSecond = dispatch_semaphore_create(0);
|
||||
ASTestDisplayNode *second = [[ASTestDisplayNode alloc] init];
|
||||
second.bounds = CGRectMake(100, 40, 42, 56);
|
||||
second.calculateSizeBlock = ^(ASDisplayNode *n, CGSize size){
|
||||
dispatch_semaphore_wait(allowSecond, DISPATCH_TIME_FOREVER);
|
||||
return CGSizeMake(10, 20);
|
||||
};
|
||||
|
||||
|
||||
ASDisplayNode *replaceMe = [[ASDisplayNode alloc] init];
|
||||
[parent addSubnode:replaceMe];
|
||||
|
||||
__block BOOL firstFinished = NO;
|
||||
[parent replaceSubnodeAsynchronously:replaceMe withNode:first completion:^(BOOL cancelled, ASDisplayNode *firstBlockArgument, ASDisplayNode *replaceMeBlockArgument) {
|
||||
XCTAssertNil(firstBlockArgument, @"Should have cancelled");
|
||||
XCTAssertNil(replaceMeBlockArgument, @"Should have cancelled");
|
||||
firstFinished = YES;
|
||||
}];
|
||||
|
||||
__block BOOL secondFinished = NO;
|
||||
[parent replaceSubnodeAsynchronously:replaceMe withNode:second completion:^(BOOL cancelled, ASDisplayNode *secondBlockArgument, ASDisplayNode *replaceMeBlockArgument) {
|
||||
XCTAssertNotNil(secondBlockArgument, @"Should have the relevant node passed in");
|
||||
XCTAssertNotNil(replaceMeBlockArgument, @"Should have the relevant node passed in");
|
||||
secondFinished = YES;
|
||||
}];
|
||||
|
||||
XCTAssertTrue(replaceMe.supernode == parent, @"didn't remove old node");
|
||||
XCTAssertTrue(first.supernode == nil, @"oops, added node too soon");
|
||||
XCTAssertTrue(second.supernode == nil, @"oops, added node too soon");
|
||||
XCTAssertFalse(first.nodeLoaded, @"first view loaded too soon");
|
||||
XCTAssertFalse(second.nodeLoaded, @"second view loaded too soon");
|
||||
|
||||
// Allow first to complete, but verify that the nodes are nil, indicating cancellation (asserts are in blocks above)
|
||||
dispatch_semaphore_signal(allowFirst);
|
||||
|
||||
// Let the work execute on the bg thread
|
||||
ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{ return firstFinished; });
|
||||
|
||||
XCTAssertTrue(first.supernode == nil, @"first should not be added to the hierarchy ever");
|
||||
XCTAssertTrue(second.supernode == nil, @"second should not yet be added to the hierarchy");
|
||||
|
||||
dispatch_semaphore_signal(allowSecond);
|
||||
ASDisplayNodeRunRunLoopUntilBlockIsTrue(^BOOL{ return secondFinished; });
|
||||
|
||||
XCTAssertTrue(first.supernode == nil, @"first should not be added to the hierarchy ever");
|
||||
XCTAssertTrue(second.supernode == parent, @"second should be added now, woot!");
|
||||
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(10, 20), [second calculatedSize]), @"Should have correct calculatedSize");
|
||||
|
||||
[parent release];
|
||||
[first release];
|
||||
[second release];
|
||||
dispatch_release(allowFirst);
|
||||
dispatch_release(allowSecond);
|
||||
}
|
||||
|
||||
- (void)testInsertSubnodeAtIndexView
|
||||
{
|
||||
[self checkInsertSubnodeAtIndexWithViewLoaded:YES layerBacked:NO];
|
||||
|
||||
Reference in New Issue
Block a user