为什么我会使用弱引用?

时间:2014-04-30 15:38:39

标签: objective-c memory-management memory-leaks automatic-ref-counting

我已经做了一些阅读,我发现了很多关于 事情的内容,但不是为什么

根据我的阅读,自动引用计数使内存管理比过去容易得多。据我所知,它类似于Java中的垃圾收集,区别在于它在编译时而不是运行时处理。即编译器插入跟踪对象有多少引用的代码,然后在该计数达到0时解除分配。

在我编写的代码中,到目前为止我已经遇到了很多问题,因为ARC因为没有使用强引用而导致对象消失。我对这些问题的看法是......始终总是使用强有力的参考!

所以我的问题是为什么弱引用甚至存在?即作为开发人员,我什么时候才能想要一个对象的引用,在我不知情的情况下,我不能依赖它来解除分配?

1 个答案:

答案 0 :(得分:2)

引用计数不是垃圾回收。

在像Cocoa Touch这样的引用计数系统中,系统在引用计数为零时解除分配对象。

现在考虑编写一个使用UITableView的应用。您必须提供一个对象作为表视图的数据源。您可能会使用UIViewController子类作为数据源。

您的视图控制器可能具有对表视图的引用。这意味着表格视图的引用计数至少为1.

您的表视图需要对其数据源的引用。这意味着视图控制器的引用计数至少为1。

假设视图控制器不再被除表视图之外的任何内容引用,并且除了视图控制器之外的任何内容都不再引用表视图。你的程序不可能再次使用这些对象,因为它没有可以跟随的引用路径,这将导致任何一个对象。我们可以说对象是“无法访问的”。即使这样,也不会破坏任何对象,因为每个对象的引用计数都为1.

在Cocoa Touch中,此方案称为保留周期。保留周期很糟糕(除非它会在某些事件发生时自动中断,如定时器触发或触摸结束),因为它会阻止系统破坏永远不会再次使用的对象。

这实际上是引用计数和垃圾收集之间的区别:GC收集程序无法再访问的所有对象。引用计数系统收集引用计数为零的所有对象。

您可以尝试编写程序,以便在不再需要视图控制器和表视图时注意。当发生这种情况时,您可以明确地中断保留周期(例如,通过将表视图的数据源设置为nil)。但总的来说,很难知道什么时候没有对象可以访问。 (这就是垃圾收集者非常好的原因:他们为你做了艰苦的工作。)

在Cocoa Touch中,为防止表视图示例中的保留周期,表视图会“弱”地引用其数据源。它保留对数据源的引用,但不会增加或减少数据源的引用计数。因此,当视图控制器和数据源都变得无法访问时,表视图的引用计数仍为1(因为视图控制器具有强引用),但视图控制器的引用计数为0.因此系统取消分配视图控制器。在释放期间,视图控制器放弃对表视图的引用,这使得表视图的引用计数为零,因此系统也可以解除分配它。

实际上,表视图不使用ARC弱引用(据我所知)。它使用ARC称之为__unsafe_unretained的引用,因为它早于ARC编写。但是你应该在你的代码中使用ARC弱引用,因为它们更安全,更有用。