ARC如何在ios中的以下代码片段中工作?

时间:2018-12-11 14:40:17

标签: objective-c automatic-ref-counting

假设我有一个返回对象指针的方法

-(MyObj *) returnMyObj {
   MyObj *obj = [MyObj alloc] init];
   return obj;
}

如果我在不分配指针的情况下调用此函数

场景1

[self returnMyObj];

如果我调用该函数并分配给这样的指针

场景2

MyObj* obj = [self returnMyObj];

在方案1中,

编译器可以在 returnMyObj 方法调用的末尾释放对象,但是在方案2中,它不能执行此操作。ARC如何确定是否需要将创建的对象保留在此位置?两种情况下方法调用是否结束?

2 个答案:

答案 0 :(得分:2)

文档article的内容如下:

  

为确保实例在仍需要时不会消失,ARC跟踪当前引用每个类实例的属性,常量和变量的数量。只要仍然存在对该实例的至少一个活动引用,ARC便不会取消分配该实例。

     

为此,无论何时将类实例分配给属性,常量或变量,该属性,常量或变量都会强烈引用该实例。该引用被称为“强”引用,因为它在该实例上保持坚决地位,并且只要该强引用仍然存在,就不允许对其进行重新分配。

ARC通过计算对对象的强引用来确定哪些对象将保留在内存中,哪些对象将被释放。

在第二种情况下,您将创建对MyObj实例的强引用,并且在使用对象时ARC不会取消分配它。在这种情况下,使用该对象的方法完成后将被释放。

答案 1 :(得分:1)

如果在该块的后面未引用obj,则优化器可以在语句末尾的情况2中绝对释放对象。

最重要的是,优化器可以看到何时引用了指针,并且可以在最后一次引用完成后立即释放它。 obj没有精确的生存期语义,因此它仅将对象的生存期延长到最后一次引用obj时,而不是obj超出范围时。

在方案1中,该引用未分配给任何变量,因此它显然没有以后的引用,并且可能会立即释放。就是说,它可能不会立即释放对象,因为returnMyObj不会将所有权转移给调用方(由于其名称)。因此,在自动释放池耗尽之前,实际上可能不会释放对象。