8

我的课堂上有一个简单的方法:

- (void)getFormWithBlock:(DataCenterResultBlock)block {
    [SomeClass doSomeLongOperationWithParam:someParam 
                                  completionBlock:^(NSData *data, NSURLResponse *response) {
                                      //Success
                                      block(aVar, YES);
                                  } errorBlock:^(NSError *error) {
                                      //Failed
                                      block(nil, NO);
                                  }];
}

我读到如果您正在异步执行某些操作,您应该将块复制到堆中,因为它们是在堆栈上分配的,并且一旦调用树倒带它就会消失。

但是在这里,我没有将它复制到堆中,但我仍然没有崩溃。为什么?谢谢

4

2 回答 2

11

块变量由 ARC 编译器自动复制到堆中

7.5。块

...

可保留对象所有者类型的 __block 变量通过使用从堆栈副本中移动的结果初始化堆副本而从堆栈中移出。

编辑我想我误解了这个问题:你问的是块对象本身,而不是块变量。在这种情况下,答案略有不同,但归结为相同:ARC 会自动执行正确的操作。

ARC 知道,如果在当前范围返回后使用块文字,则必须复制它们。非 ARC 代码需要显式复制和自动释放返回的块:

return [[^{
    DoSomethingMagical();
} copy] autorelease];

使用 ARC,这简单地变为:

return ^{ DoSomethingMagical(); };

(从这里

于 2012-07-11T14:00:44.733 回答
1

[SomeClass doSomeLongOperationWithParam:completionBlock:errorBlock:]应该复制完成和错误块。

如果您查看该方法的实现,它可能正在做正确的事情并复制您传入的块。ARC 或没有 ARC,该方法应该复制这些块。

于 2012-08-21T20:41:48.483 回答