带块的保留周期

时间:2015-11-09 03:28:18

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

关于使用块的保留周期的问题。在ARC模型中。

比如说,视图控制器的实例名为' vc',它保存对块的引用。在块中,vc用于某些操作:

{

    //this is a piece of code snippet in vc
    self.vcBlock = {

        [self someAction];

    }

}

据我所知,这会导致保留周期,因为vc对块有很强的引用,而块也会对vc有强引用。

但是如何在块中引用vc的成员变量:

{

    //this is a piece of code snippet in vc
    self.vcBlock = {

        [self.obj someAction];

    }

}

这会导致保留周期吗?我认为这些参考文献的关系可以解释如下:

enter image description here

那么,我认为没有保留周期存在,有什么问题吗?

4 个答案:

答案 0 :(得分:3)

属性访问在编译时转换为方法调用,因此在第二个示例中,它仍然是自我保留的,并且您具有完全相同的循环。

答案 1 :(得分:3)

表达式self.obj在运行时进行评估,这需要块保持self的值,因此您仍然有一个循环。

但是,如果您的图表是您想要的关系,那就是您的块具有对创建块时self.obj 引用的对象的引用,那么您可以通过使用临时局部变量来简单地实现这一点。即代码如下:

SomeType objRef = self.obj;
self.vcBlock = ^{ ... [objRef someAction]; ... };

这可以避免循环,因为self.obj返回的(对象引用)首先被复制到本地objRef,然后是成为块保存值的一部分(又名 environmemt )。

在这种情况下,这是一种常见的方法,但请记住,如果self.obj的值在块执行之前发生变化,那么该块的变化将 - 似乎是你想要的图表。

另请注意,循环本身不是问题,您可以创建循环,然后打破它们而不会出现问题 - 实际上这并不罕见。如果循环导致无法回收的资源(如内存),则循环只是一个问题。

HTH

答案 2 :(得分:1)

它确实存在保留周期,vcBlock拥有对self(vc)的强引用, 或者你可以把它作为

[[self obj] someAction];

如果我们以这样的另一种形式调用此方法(如果obj是ivar)

[_obj someAction];//in fact ,it's equivalent to [self->obj someAction]

所以该块总是对自己有强烈的引用。

答案 3 :(得分:1)

在第二种情况下,您可以避免保留周期:

{
    MyObject* obj = self.obj;
    self.vcBlock = ^{ [obj someAction]; };
}