关于块中对象的Apple文档

时间:2013-06-06 15:31:14

标签: iphone ios objective-c-blocks retain-cycle

关于此事的Apple文档声明:

  

复制块时,会创建对对象的强引用   块内使用的变量。如果你在里面使用一个块   方法的实施:

     

如果通过引用访问实例变量,则引用强引用   为自己做的;

     

如果按值访问实例变量,则强引用   对变量做了。

并且有代码示例:

dispatch_async(queue, ^{

// instanceVariable is used by reference, a strong reference is made to self

doSomethingWithObject(instanceVariable);

});





id localVariable = instanceVariable;

dispatch_async(queue, ^{

    /*

  localVariable is used by value, a strong reference is made to localVariable

  (and not to self).

*/

doSomethingWithObject(localVariable);

});

但对我来说没有任何意义。如何按值访问实例变量?你总是通过参考访问它吗?无论是self.myVariable还是id newName = self.myVariable,都始终是参考。

然后这个例子不太清楚他们的意思。为什么在第一种情况下自我保留,在第二种情况下不是?它没有在任何地方使用,所以为什么要阻止它?

1 个答案:

答案 0 :(得分:2)

当您使用实例变量时,编译器会将您看到的ivar名称转换为self->iVar,这就是该块使用的内容。您甚至可以在代码中执行此操作 - 尝试访问前缀为self->的内容。

编辑:所以在第一种情况下,该块会捕获self,因为它需要它来访问instanceVariable,就像self-> instanceVariable一样。因此,它将使用块最终执行时的任何值。由于self是一个对象,因此会被保留。

在第二种情况下,临时变量(对象与否)被赋予当前值self-> instanceVariable,无论当时是什么。当块捕获localVariable时,它会保留对象,并且在dispatch_async调用之后,ARC释放localVariable,因此块现在是唯一保留localVariable的块。从那时起,类可以更改实例变量,它不会影响捕获的块(一个例外 - 如果对象是一个可变对象,那么块将使用它运行时的任何内容 - 原因是在这种情况下不要使用可变对象,而是使用不可变副本。