为什么Objective-C块仍然可以工作而不将其复制到堆中?

时间:2012-07-11 13:40:20

标签: objective-c ios cocoa-touch

我班上有一个简单的方法:

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

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

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

2 个答案:

答案 0 :(得分:10)

Block variables are copied to the heap automatically by ARC compilers

  

7.5。块

     

...

     通过使用从堆栈副本移动的结果初始化堆副本,将

__可保留对象所有者类型的块变量移出堆栈。

编辑我想我误解了这个问题:你问过块对象自己,而不是阻止变量。在这种情况下,答案略有不同,但归结为相同:ARC自动做正确的事情。

  

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

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

使用ARC,这只会变成:

return ^{ DoSomethingMagical(); };

(来自here

答案 1 :(得分:1)

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

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