在下面的示例中,我不明白为什么localVariable
按doSomethingWithObject
中的值访问self
。是什么促成了转换?您如何区分按值访问变量和通过引用访问变量?如果可能的话,我希望看到更多相关的例子。
以下是Apple Blocks Programming Topics的摘录,并显示了如何在块中保留实例变量。
如果你在里面使用一个块 执行方法,规则 用于对象的内存管理 实例变量更加微妙:
- 如果您通过引用访问实例变量,则会保留
dispatch_async(queue, ^{ // instanceVariable is used by reference, self is retained doSomethingWithObject(instanceVariable); }); id localVariable = instanceVariable; dispatch_async(queue, ^{ // localVariable is used by value, localVariable is retained (not self) doSomethingWithObject(localVariable); });
;- 如果按值访问实例变量,则保留变量。
以下示例说明了 两种不同的情况:
{{1}}
答案 0 :(得分:12)
这是因为当您直接访问实例变量时,编译器(或多或少)会将其转换为结构成员查找。所以:
[ivar doSomething];
变为
[self->ivar doSomething];
由于需要self
,因此必须保留self
。但是,当您将指针值复制到新变量中时,您知道更长时间需要self
结构来知道指针值是什么,因此self
不需要保留,因为指针值可以从堆栈中复制const
。实例变量不会发生这种情况(因为在创建块和执行块时,ivar可能会发生变化)。
澄清:
self
),以便查找始终成功。如果它没有这样做,那么将来可能会释放self
,现在结构查找会导致访问不良(最有可能)并且您的应用程序会崩溃。self
,因为self
不再涉及检索相关对象的地址