在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]
。
答案 0 :(得分:10)
编辑:我之前的回答可能是错误的。
ARC docs的一些选定摘录说:
第3。可保留对象指针
可保留对象指针(或可保留指针)是可保留对象指针类型的值(可保留类型)。有三种可保留的对象指针类型:
<强> 4.2。语义强>
评估赋值运算符时会发生赋值。语义因资格而异:
<强> 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
。