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

时间:2012-05-04 17:11:36

标签: objective-c automatic-ref-counting objective-c-blocks ivar

在ARC下面假设以下代码,

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

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

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

My previous question暗示在通过@property分配时会复制它。但是,今天我使用了上面的代码并收到了一个EXC_BAD_ACCESS,它通过更改为

来修复

_ivarResponseHandler = [responseHandler copy]

2 个答案:

答案 0 :(得分:10)

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

ARC docs的一些选定摘录说:

第3。可保留对象指针

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

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

<强> 4.2。语义

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

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

<强> 4.4.1。对象

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

<强> 7.5。块

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

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

答案 1 :(得分:4)

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

  

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

我将“这些语义”用于表示整个文档,但如果“这些语义”仅引用第7.5节,则ARC仅为块捕获的块插入Block_copy