objective-c - 为什么 Objective-C block 在不将其复制到堆中的情况下仍然有效?

标签 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);
                                  }];
}

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

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

最佳答案

Block variables are copied to the heap automatically by ARC compilers :

7.5. Blocks

...

__block variables of retainable object owner type are moved off the stack by initializing the heap copy with the result of moving from the stack copy.

编辑 我想我误解了这个问题:您询问的是 block 对象自身,而不是 block 变量。这种情况下的答案略有不同,但归结起来是一样的:ARC 会自动执行正确的操作。

ARC knows that block literals must be copied if they're used after the current scope returns. Non-ARC code needs to explicitly copy and autorelease returned blocks:

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

With ARC, this simply becomes:

return ^{ DoSomethingMagical(); };

(来自 here)

关于objective-c - 为什么 Objective-C block 在不将其复制到堆中的情况下仍然有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11433943/

相关文章:

ios - Firebase Crashlytics 无法激活

ios - iOS 中核心数据的使用

objective-c - 在 uilabel 中找到文本的位置 {x,y}

ios - "Warning: Attempt to present * on * which is already presenting *"的断点

ios - Urban Airship 集成错误 arm64 不是被链接的架构 (armv7)

ios - xcode 模拟器 - 找不到库

iphone - 为什么 viewDidAppear 没有被触发?

ios - 如何检测 UIView 大小何时在 swift ios xcode 中更改?

objective-c - 没有上下文的 NSRectFill 会导致调试警告

ios - 从以编程方式创建的 UIPickerView 获取数据