块、栈和堆

4

我使用 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中的block时没有使用-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操作吗?

1个回答

1
不仅是在块内调用另一个块,而是任何直接引用都会导致复制。包括将其作为参数传递给其他内容。对于块中的ObjC类型也是如此(除了它们只是简单的保留,而不是复制)。

谢谢,这很有道理。将其与其他ObjC类型进行比较有助于我理解一个块将触发ARC编译器来保留块所引用的任何标准ObjC对象。 - David Y.
即使没有ARC,使用块也是很奇怪但非常有用的。这也可以理解,因为块比至少一个操作系统发布周期早出现了。 - Stripes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接