20

假设ARC下的代码如下,

typedef void (^MyResponseHandler) (NSError *error);
@interface MyClass : NSObject
{
    MyResponseHandler _ivarResponseHandler;
}

- (void)myMethod:(MyResponseHandler)responseHandler
{
    _ivarResponseHandler = responseHandler;
    ...
}

问题:分配给 ivar 时,block 是否会自动复制到堆中?

我之前的问题暗示它在通过@property. 但是,今天我使用了上面的代码并收到了一个EXC_BAD_ACCESS通过更改为

_ivarResponseHandler = [responseHandler copy].

4

2 回答 2

10

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

ARC 文档中的一些节选说:

3. 可保留对象指针

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

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

4.2. 语义

在评估赋值运算符时会发生赋值。语义因限定而异:

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

4.4.1。对象

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

7.5。块

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

所以我认为答案是可能的,取决于优化器。

于 2012-05-14T01:14:42.527 回答
4

您的问题和解决方案表明我对您其他问题的回答可能是错误的。我基于clang Objective-C Automatic Reference Counting 文档第 7.5 节的最后一段:

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

我认为“这些语义”是指整个文档,但如果“这些语义”仅指第 7.5 节,那么 ARC 只Block_copy为被块捕获的块插入 a。

于 2012-05-04T17:23:23.407 回答