在 ARC 下,块在直接分配给 ivar 时会自动复制



假设在 ARC 下有以下代码,

typedef void (^MyResponseHandler) (NSError *error);
@interface MyClass : NSObject
{
    MyResponseHandler _ivarResponseHandler;
}
- (void)myMethod:(MyResponseHandler)responseHandler
{
    _ivarResponseHandler = responseHandler;
    ...
}

问:块在分配给 ivar 时是否会自动复制到堆中?

我之前的问题暗示它在通过@property分配时被复制。 但是,今天我使用了上面的代码并收到了一个EXC_BAD_ACCESS,该已通过更改为

_ivarResponseHandler = [responseHandler copy] .

编辑:我之前的答案可能是错误的。

ARC文档中的一些摘录说:

3. 可保留的对象指针

可保留对象指针(或可保留指针(

是可保留对象指针类型(可保留类型(的值。有三种可保留的对象指针类型:

  • 块指针(通过将插入符号 (^( 声明符符号应用于函数类型而形成(

4.2. 语义

赋值在计算赋值运算符时发生。语义因限定条件而异:

  • 对于__strong对象,首先保留新的 pointee;其次,用原始语义加载左值;第三,使用原始语义将新 pointee 存储到左值中;最后,释放旧的 pointee。这不是以原子方式执行的;必须使用外部同步来确保在面对并发加载和存储时的安全。

4.4.1. 对象

如果使用可保留的对象所有者类型声明对象,但没有显式所有权限定符,则其类型将隐式调整为具有__strong限定符。

7.5. 块

除了作为初始化__strong参数变量或读取__weak变量的一部分完成的保留之外,每当这些语义要求保留块指针类型的值时,它都具有Block_copy的效果。当优化程序看到结果仅用作调用的参数时,它可能会删除此类副本。

所以我认为答案是也许,取决于优化器。

你的问题和解决方案表明我对你另一个问题的回答可能是错误的。我基于clang Objective-C自动引用计数文档第7.5节的最后一段:

除了作为初始化__strong参数变量或读取__weak变量的一部分完成的保留之外,每当这些语义要求保留块指针类型的值时,它都会产生Block_copy的效果。当优化程序看到结果仅用作调用的参数时,它可能会删除此类副本。

我将"这些语义">

表示整个文档,但如果"这些语义"仅指第 7.5 节,则 ARC 仅为块捕获的块插入Block_copy

最新更新