在使用Xcode 4.2和ARC之前,我已经编写了以下代码,然后才能了解如何将块从堆栈复制到堆中。
-(void) downloadWithBlock:(void (^)(void))callbackBlock;
{
// start the data download in the background...
NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{
// synchronous download code
}];
[backgroundOperationQueue addOperation:backgroundOperation];
NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{
callbackBlock();
}];
[foregroundOperation addDependency:backgroundOperation];
[[NSOperationQueue mainQueue] addOperation:foregroundOperation];
}
代码有效,但我不相信它,因为我不理解它。在代码的另一部分中,我在调用存储在ivars中的块而不使用-copy时遇到了应用程序崩溃。这让我想知道这部分代码是否应该像这样重写:
-(void) downloadWithBlock:(void (^)(void))callbackBlock;
{
void(^heapBlock)(void) = [callbackBlock copy];
// start the data download in the background...
NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{
// synchronous download code
}];
[backgroundOperationQueue addOperation:backgroundOperation];
NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{
heapBlock();
}];
[foregroundOperation addDependency:backgroundOperation];
[[NSOperationQueue mainQueue] addOperation:foregroundOperation];
}
我唯一关心的是更好地理解块指针的工作原理。这些代码部分中的任何一个都可接受在另一个块中调用块是否会触发编译器插入隐藏的Block_copy操作?
答案 0 :(得分:1)
不仅在块内调用块,而且任何直接引用块都会导致副本。包括将其作为参数传递给其他人。块中的ObjC类型也是如此(除了它是一个简单的保留,而不是它们的副本)。