Objective c 带块的保持循环

Objective c 带块的保持循环,objective-c,objective-c-blocks,retain-cycle,Objective C,Objective C Blocks,Retain Cycle,关于块保留循环的一个问题。在圆弧模型中 例如,一个名为“vc”的视图控制器实例,它保存对一个块的引用。在块中,vc用于某些操作: { //this is a piece of code snippet in vc self.vcBlock = { [self someAction]; } } 我理解这会导致retain循环,因为vc对块有一个强引用,而块也会对vc有一个强引用 但在块中引用vc的成员变量如何: { //this is a

关于块保留循环的一个问题。在圆弧模型中

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

{

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

        [self someAction];

    }

}
我理解这会导致retain循环,因为vc对块有一个强引用,而块也会对vc有一个强引用

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

{

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

        [self.obj someAction];

    }

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


因此,我认为不存在保留周期,有问题吗?

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

属性访问在编译时转换为方法调用,所以在第二个示例中,保留的仍然是self,并且您拥有完全相同的循环。

它确实存在保留循环,vcBlock对self(vc)有很强的引用, 或者你可以把它当作

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


因此块始终保持对self的强引用。

它确实存在,vcBlock保持对self(vc)的强引用, 或者你可以把它当作

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


因此,块始终保持对self的强引用。

在第二种情况下,可以避免保留循环:

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

在第二种情况下,可以避免保留循环:

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

表达式
self.obj
是在运行时计算的,这要求块保持
self
的值,因此仍然有一个循环

但是,如果您的图是您想要的关系,即您的块在创建块时引用了由
self.obj
引用的对象,那么您可以通过使用临时局部变量来实现这一点。即,代码大致如下:

SomeType objRef = self.obj;
self.vcBlock = ^{ ... [objRef someAction]; ... };
这避免了循环,因为首先将
self.obj
返回的值(对象引用)复制到本地
objRef
,然后该值成为块的保存值(也称为其环境)的一部分

在这种情况下,这是一种常见的方法,但请记住,如果在执行块之前,
self.obj
的值发生变化,那么块将不会看到该变化,这似乎是您希望从图表中看到的

还要注意的是,周期本身并不是问题,您可以创建周期,然后在没有问题的情况下打破它们——事实上,这并不罕见。只有当循环导致未回收的资源(如内存)时,它才是一个问题


HTH

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

但是,如果您的图是您想要的关系,即您的块在创建块时引用了由
self.obj
引用的对象,那么您可以通过使用临时局部变量来实现这一点。即,代码大致如下:

SomeType objRef = self.obj;
self.vcBlock = ^{ ... [objRef someAction]; ... };
这避免了循环,因为首先将
self.obj
返回的值(对象引用)复制到本地
objRef
,然后该值成为块的保存值(也称为其环境)的一部分

在这种情况下,这是一种常见的方法,但请记住,如果在执行块之前,
self.obj
的值发生变化,那么块将不会看到该变化,这似乎是您希望从图表中看到的

还要注意的是,周期本身并不是问题,您可以创建周期,然后在没有问题的情况下打破它们——事实上,这并不罕见。只有当循环导致未回收的资源(如内存)时,它才是一个问题


你的意思是:Obj*Obj=[self-getObjc];[obj someAction]?类似于此,除非在属性声明中有
getter=myGetter
属性,否则该方法将与属性具有相同的名称。在您的示例中,setter将是
setObj
。另外,请注意,直接使用实例变量(
\u obj
)对您没有帮助。它仍然保留
self
,因为
\u obj
是一个结构成员,ARC不会(不能)保留在结构级别;[obj someAction]?类似于此,除非在属性声明中有
getter=myGetter
属性,否则该方法将与属性具有相同的名称。在您的示例中,setter将是
setObj
。另外,请注意,直接使用实例变量(
\u obj
)对您没有帮助。它仍然保留
self
,因为
\u obj
是结构成员,而ARC不会(不能)保留在结构级别。