为什么我会使用弱引用?

问题描述:

我做一点阅读,我已经找到了很多关于怎么回事儿,但不是为什么为什么我会使用弱引用?

从我已阅读,自动引用计数,内存管理比一个更容易它会在过去。据我了解,它类似于Java中的垃圾收集,不同之处在于它在编译时而不是运行时处理。即编译器会插入跟踪对象有多少引用的代码,然后在计数达到0时将其解除分配。

在我写的代码中,至今我已经遇到了很多与对象消失有关的问题,这是因为ARC因为我没有使用强大的参考资源而取消分配它们。我从这些问题中解脱出来是......总是总是使用强烈的参考!

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

+2

Java有弱引用,你知道。 :) –

+2

仅供参考 - ARC与垃圾收集不同。 ARC就是编译器自动为你添加对'retain'和'release'的调用。它与垃圾收集完全不同。 – rmaddy

+0

也许最常见的例子是当对象A具有对象B作为其代表时。对象A需要使用对象B,但它不拥有它,因此它会很弱。 – Gruntcakes

引用计数不是垃圾收集。

在参考计数系统一样可可触摸,系统当其引用计数变为零重新分配的对象。

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

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

你的表视图需要它的数据源的引用。这意味着视图控制器具有至少为1

参考计数假设视图控制器由除了表视图任何不再被引用,并且该表视图是由除视图控制器任何不再参考。你的程序不可能再次使用这些对象,因为它没有可以引用的引用路径,这将导致任何对象。我们可以说对象是“无法访问”的。即使在那时,也不会销毁任何物品,因为每个物品的参考计数都为1.

在Cocoa Touch中,此场景称为保留周期。保留周期不好(除非在发生某些事件时它会自动断开,如定时器触发或触摸结束),因为它可以防止系统销毁永远不会再使用的对象。

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

你可以尝试编写程序的通知时,视图控制器和表视图不再需要。发生这种情况时,您可以明确地中断保留周期(例如,通过将表视图的数据源设置为零)。但总的来说,很难知道什么时候没有任何对象可到达。 (这就是为什么垃圾收集器非常好:他们为你做了很多努力。)

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

事实上,表视图不使用ARC弱引用(据我所知)。它使用ARC称之为__unsafe_unretained的引用,因为它是在ARC之前很久才写入的。但是你应该在代码中使用ARC弱引用,因为它们更安全,更实用。

+0

谢谢,这个解释真的很有帮助! – Chris

+0

'__unsafe_unretained'是如此命名的,因为在ARC下,一旦引用的对象被释放,普通的'weak'引用会被自动赋值为'nil'。既然你可以在Objective-C中提供'nil',这可以帮助防止崩溃(通常)。 '__unsafe_unretained'引用对保留计数没有贡献,但是如果你在释放一个消息后发送消息,你会得到一个'EXC_BAD_ACCESS'错误(可能)。 –