关于使用块的保留周期的问题。在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];
}
}
这会导致保留周期吗?我认为这些参考文献的关系可以解释如下:
那么,我认为没有保留周期存在,有什么问题吗?
答案 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]; };
}