我必须在这里复制一个块吗?

时间:2012-01-13 20:08:20

标签: objective-c objective-c-blocks

我知道你必须复制块才能让它们在堆栈帧退出后留下来。但是,这如何应用于嵌套块中使用的堆栈分配块,如下面的代码示例所示:

- doSomethingFunkyThenCall:(void(^)(int someValue))callback
{
    [[NSOperationQueue currentQueue] addOperationWithBlock:^{
        // ... do some work here, potentially nesting into further blocks ...
        callback(result);
    }];
}

显然,doSomethingFunkyThenCall:堆栈帧将在执行回调之前终止,因此必须复制它。但这会在调用addOperationWithBlock:时自动发生还是我必须手动执行?

2 个答案:

答案 0 :(得分:3)

最有可能的是,它会自动发生。 Cocoa的设计原则通常意味着您不负责对象(它们的内存管理,传递块[事实上,它们实现为正确的Objective-C对象]等),而您还没有创建。因此,您可以将您收到的块作为参数传递下去,运行时将根据需要对其进行管理。

答案 1 :(得分:0)

是的,您应该在此方法的顶部执行callback = [[callback copy] autorelease];

块中使用的对象会自动保留,但发送堆栈块保留实际上什么都不做(因为retain的语义要求它返回接收器),所以一旦我们离开它创建的帧就会消失。 / p>

来源:
http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html http://thirdcog.eu/pwcblocks/#objcblocks

编辑:事实证明我错了。 @bbum在下面指出Block_copy将递归复制,并且由于addOperationWithBlock:复制了它的块,所以也会复制回调。