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

bea*_*ain 20 objective-c objective-c-blocks ivar automatic-ref-counting

在ARC下面假设以下代码,

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

- (void)myMethod:(MyResponseHandler)responseHandler
{
    _ivarResponseHandler = responseHandler;
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

我之前的问题暗示它是在通过a分配时复制的@property.但是,今天我使用了上面的代码并收到了EXC_BAD_ACCESS修改后修改的代码

_ivarResponseHandler = [responseHandler copy].

sbo*_*oth 10

编辑:我以前的回答可能是错的.

一些选定的ARC文档摘录说:

3.可保留的对象指针

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

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

4.2.语义

在评估赋值运算符时发生赋值.语义因资格而异:

  • 对于__strong对象,首先保留新的指针对象; 第二,左值加载了原始语义; 第三,新的指针被存储到具有原始语义的左值中; 最后,老指针被释放了.这不是原子地执行的; 必须使用外部同步,以便在并发加载和存储时使其安全.

4.4.1.对象

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

7.5.块

除了在初始化__strong参数变量或读取__weak变量时执行的保留之外,每当这些语义调用保留块指针类型的值时,它都具有Block_copy的效果.当优化器看到结果仅用作调用的参数时,可以删除这些副本.

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

  • 感谢所有的努力sbooth.哇,这个文档很难理解.实际上,我会读到编译器 - 将插入一个Block_copy.似乎ivar默认为__strong,因此赋值将"调用保留块指针类型的值",从而插入Block_copy.我认为有一个明确的答案会很棒,我想现在我已经满足于在`@property(copy)`中存储块. (2认同)

rob*_*off 4

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

\n\n
\n

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

\n
\n\n

我将 \xe2\x80\x9c 这些语义\xe2\x80\x9d 表示整个文档,但如果 \xe2\x80\x9c 这些语义\xe2\x80\x9d 仅指第 7.5 节,那么 ARC 只会插入 a 来Block_copy表示被一个块捕获的块。

\n

  • 我采访了撰写本节的 Apple 工程师。他说“这些语义”指的是整个文档。因此应该自动插入一个“Block_copy”。看来这可能是早期块的一个错误,后来被修复了。 (3认同)