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:
Nadine Salter
2014-09-29 14:05:17 -07:00
parent c51a58cd85
commit af6c11ade7
3 changed files with 0 additions and 272 deletions

View File

@@ -221,32 +221,6 @@
*/ */
- (void)replaceSubnode:(ASDisplayNode *)subnode withSubnode:(ASDisplayNode *)replacementSubnode; - (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. * @abstract Remove this node from its supernode.
* *

View File

@@ -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 @end
@implementation ASDisplayNode (Debugging) @implementation ASDisplayNode (Debugging)

View File

@@ -914,167 +914,6 @@ static inline BOOL _CGPointEqualToPointWithEpsilon(CGPoint point1, CGPoint point
[d release]; [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 - (void)testInsertSubnodeAtIndexView
{ {
[self checkInsertSubnodeAtIndexWithViewLoaded:YES layerBacked:NO]; [self checkInsertSubnodeAtIndexWithViewLoaded:YES layerBacked:NO];