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

0xS*_*ina 8 cocoa-touch objective-c ios

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

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

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

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

das*_*ght 11

块编译器会自动将块变量复制到堆中:

7.5.块

...

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

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

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

return [[^{
    DoSomethingMagical();
} copy] autorelease];
Run Code Online (Sandbox Code Playgroud)

使用ARC,这简单地变成:

return ^{ DoSomethingMagical(); };
Run Code Online (Sandbox Code Playgroud)

(从这里)