在ARC中,对于本地变量使用__weak关键字

3

当您在ARC中编写以下代码时

__weak NSMutableArray* array = [[NSMutableArray alloc] init];

编译器会提示警告或错误并说“将保留对象分配给弱变量。分配后对象将被释放”,但如果您这样写:
__weak NSMutableArray* array = [NSMutableArray array];

没有错误。

我想知道第二种用法在某些情况下是否合理?从内存管理的角度来看,这两个代码有什么区别?它是如何工作的?

3个回答

1
它们是相同的,因为你会立即失去对象。编译器除了alloc init之外无法知道可能性,即对象将被丢失。

1
谢谢。我在考虑编译器,不知道[NSMutableArray array]是一个对象的创建。这对我来说很有意义。 - Entreri

1

编译器可能无法知道非常微小的差异。

让我们来看一个不可变版本:[NSArray array] 可以每次返回相同的静态对象。因此,您的弱引用变量将指向一个有其他地方强引用的有效对象。或者考虑单例模式。另一方面,当调用alloc/init时,约定俗成的是您是该对象的唯一所有者,这通常会使您失去任何东西。

此外,工厂方法确实更像是(功能性的)方法。无论如何,它不能很好地传达其返回内容的所有权。对于一个自动释放的对象,不清楚您是唯一的所有者还是共享所有者。


0

在第一种形式中,该方法返回一个已保留对象。ARC确保,在调用现场没有强引用时释放该对象。使用弱引用能够立即做到这一点,因此编译器会发出警告或错误。

在第二种形式中,该方法返回一个未保留对象。在这种情况下,编译器必须确保在返回边界上仍然有效。当从这样的函数或方法返回时,ARC会保留return语句评估点的值,然后离开所有本地作用域,并平衡保留同时确保该值跨越调用边界生存。也就是说,编译器创建了一个强引用。这个强引用将由编译器生成的代码自动释放。

因此,在这种情况下没有出现错误或警告。

在最坏的情况下,持有该对象可能需要使用autorelease池。但是编译器可以应用某些优化来避免这种情况。因此,我们不应假设返回的对象存在于自动释放池中。

请参阅规范:http://clang.llvm.org/docs/AutomaticReferenceCounting.html#id14

另请参阅 SO 上的这个问题: [NSMutableArray array] 与 [[NSMutableArray alloc] init] 之间的区别


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接