【问题标题】:When a view controller is dealloc'd under ARC, are it's properties also dealloc'd if another object has a strong reference?当视图控制器在 ARC 下被释放时,如果另一个对象具有强引用,它的属性是否也会被释放?
【发布时间】:2013-06-06 08:25:30
【问题描述】:

我有一个使用外围滑入/滑出右手视图控制器的地图应用程序,很像下面显示的 Google 地图应用程序 (source):

在我的应用程序中,这个滑出视图有一个 weak delegate 属性,我将地图视图控制器设置为委托(例如,mapOptionsViewController.delegate = self 来自内部 myMapViewController)。不过,我也希望使用右侧的幻灯片查看其他类型的信息。例如。显示用户在地图上选择的餐厅菜单,menuViewController

我的问题是,如果我将mapOptionsViewController 换成menuViewController,我还需要手动将nilmapOptionsViewController.delegate 换出myMapViewController 吗?我担心的是即使mapOptionsViewController在我切换到menuViewController时被dealloc'd/disposed,因为myMapViewController仍然指向旧的mapOptionsViewController.delegatemapOptionsViewController.delegate的内存不会被释放堆。

所以基本上,如果你有一个对象视图控制器foo(我的地图),它是另一个视图控制器bar(地图选项)的代表,例如bar.delegate = foo,然后你切换出bar对于baz(餐厅菜单),我是否需要从foo 设置bar.delegate = nil。或者,当视图控制器 delegate 包含在被释放为 baz 时,bar nil out delegate 会被释放吗?

【问题讨论】:

  • 不要考虑分配和释放。想想所有权:释放和保留。强属性会这样做,弱属性不会。
  • 如果我错了,请纠正我,但在这种情况下,strong/weak 的区别并不是无关紧要的,因为bar.delegate = foo 创建了一个从foo 到@987654353 的强指针@ (我假设?)。尽管bar 中的delegate 属性被声明为weak,但这并不能改变foo(地图)在我们完成bar 之后仍然强烈指向它的事实,并且所以bar.delegate 还在记忆中吗?
  • "bar.delegate = foo 创建一个从 foobar.delegate 的强指针" - 为什么会这样? bar.delegateweak
  • 也许是我对弱指针的理解有缺陷。我对弱指针的定义一直是“只要其他人强烈指向它,就保持它”。如果从foo 内部调用的bar.delegate = self 不是强指向delegate 属性的示例,该属性已在bar 的类中声明为weak,您能否提供一个示例说明它是什么?跨度>
  • 好吧,也许这在语义上是等价的,但你把它复杂化了。 weak 引用不进行引用计数。这暗示如果你想保持对象存活,就需要一个强引用。但实际上这些属性不需要相互了解(作为一个实现细节,它们可能会这样做,因为当它们的值被释放时它们会自动被清空,但这不是要考虑/依赖的)。如果你有一个指向对象的强指针和弱指针,没有别的,那么将弱指针归零没有效果,但将强指针归零

标签: objective-c automatic-ref-counting


【解决方案1】:

所以基本上,如果您有一个对象视图控制器 foo(我的地图),它是另一个视图控制器 bar(地图选项)的委托,例如 bar.delegate = foo,然后您将 bar 切换为 baz(餐厅菜单),我是否需要从 foo.delegate = nil 设置 bar.delegate = nil。或者,当视图控制器委托包含在由于被 baz 替换而被解除分配时,是否会禁止 nil out 委托?

那么,让我们看看我是否明白你在做什么。

你有一个bar,对foo 有一个弱引用,所以bar.delegate = foo。您还必须有其他东西(我将其称为qux)并强烈引用相同的foo,否则您的foo 将会消失。假设相关属性是qux.menuThingy = foo

然后你做qux.menuThingy = baz。你的bar 会怎样?

如果 qux 是唯一对 foo 具有强引用的对象,则现在不再有对 foo 的强引用,因此 foo 被释放。因为您使用了弱引用,bar.delegate 已自动为您设置为 nil。你不必自己做。

如果还有另一个对象对foo 有强引用,那么foo 仍然存在并且尚未被释放。

【讨论】:

  • 接近我所描述的。该地图是foo,出于所有意图和目的,它在应用程序运行的整个过程中都存在。右侧是barbaz,具体取决于地图选项或餐厅菜单是否占据右侧面板。 barbaz 应该在整个应用程序中反复交换 - bar 被破坏以为 baz 让路,反之亦然。我的问题是,如果在foo 中我们有bar.delegate = self,我们是否会阻止bar 被完全摧毁(在内存方面)为baz 让路。
  • ... 即因为foo 在应用程序运行的整个过程中一直存在(不像barbaz 应该被完全创建/销毁多次)并持有一个强指针凭借在foo 中调用bar.delegate = self
  • 哦,所以你问bar.delegate = foo 是否足以阻止bar 被破坏?不,这不对。这不算作对bar 的强引用,因此bar 将在没有更多强引用时被销毁。
【解决方案2】:

一句话,没有。只要一个对象仍然有强引用,并且最后一个有字符串引用的对象没有被释放,它就不会被释放。或者,你有一个错误。

此外,weak 引用将在引用它的对象被释放时自动归零。但是assign 不会。

【讨论】:

  • 对,所以我认为我想在这里验证的关键是,如果我将bar 设置为nil,那么bar.delegate 也将是niled,即使另一个对象foo 有指向它的强指针吗?
  • 如果您将bar 设置为nil 并且它是唯一的强指针,则对象bar 指向的是dealloc'd(即不再有bar.delegate - @987654333 @ 本身已经消失)。如果foo 仍然有指向它的强指针,它仍然存在。这些只是驻留在堆中的指针,而不是对象本身——这不是 C++。
猜你喜欢
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2011-04-08
  • 1970-01-01
  • 2011-05-20
相关资源
最近更新 更多