【问题标题】:UIViewControllers And ARCUIViewControllers 和 ARC
【发布时间】:2012-12-10 06:24:51
【问题描述】:

因此,经过深思熟虑并在花时间尝试搜索内存管理问题时有点沮丧后,我做了一些研究,最终屈服于更改为 ARC。而且相对无痛。然而,一个与我的 UIViewControllers 相关的新问题浮出水面,弧前它们都像宣传的那样工作,我将它们推入堆栈,它们出现了,我将它们从堆栈中弹出,调用了他们的 dealloc 方法,每个人都很高兴。切换到 ARC,永远不会调用 dealloc。这是不幸的。所以我对这个问题做了一些研究,让我列出我在做什么和/或不做什么

.首先,我推入堆栈的视图没有明确声明为强。

. 子类拥有的父类的委托是 unsafe_unretained,但是为了覆盖基础,我什至注释掉了将委托设置为父类,不高兴。

. 关闭 NSzombies 显然这会导致东西停留在启用 ARC 的代码中

.根据布拉德·拉森在Memory not released in ios view hierarchy 中的回答,我从这里更改了我的代码

if (_friendsListVC == nil) 
{
    _friendsListVC = [[FriendsListViewController alloc] initWithNibName:nil bundle:nil];
    _friendsListVC.delegate = self;
}

[self.navigationController pushViewController:_friendsListVC animated:YES]; 

(_friendsListVC 是一个成员变量)。至此

 FriendsListViewController *fVC = [[FriendsListViewController alloc] initWithNibName:nil bundle:nil];
 //fVC.delegate = self;
 [self.navigationController pushViewController:fVC animated:YES]; 

再次没有 Joy,dealloc 断点永远不会被击中,问题是我在我的应用程序中推送和弹出了很多视图,所以这只会导致更多的内存问题,除了我改用 ARC 的那些希望修复...

另外请注意,我在这个视图中有一些代码块以及其他一些代码块,但我不使用 self,我也读到它是自我保留的,所以当涉及到代码块时,你应该弱 ref。

我被难住了,谁能解释一下 ARC 在做什么?或者我不尊重使用 ARC 做什么?并且为了将来参考,您想要推送到 ARC 中视图层次结构的所有视图都不是实例变量吗?

提前致谢。

【问题讨论】:

    标签: ios uiviewcontroller automatic-ref-counting dealloc


    【解决方案1】:

    我发现问题出在哪里,但它并没有修复没有被释放的其他控制器,这些完全是出于不同的原因。因此,为了传播知识和减轻其他人的痛苦,我将列出可能导致保留周期的事情的数量,主要与 ARC 和 UIViewControllers 和代码块有关

    1. 不要强烈引用您正在推进的视图。

    2. 1234563很强大,因为我认为 ARC 转换器会为我做到这一点。
    3. 关闭 NSZombies。不会一直介意你,只是为了确保何时调用 dealloc 语句。

    4. 不要在代码块中直接引用 self,这会导致保留循环。如果需要使用self,在块外执行以下操作(然后使用weakself)

      __unretained_unsafe className *weakSelf = self;

    5. 当心静态引用,我对此不确定,但我有一个方法,它接收两个实例化的视图控制器并将一个推到另一个之上,引用被分配给其中的两个静态实例类(不要问为什么),在使用后将它们归零后似乎解决了我的问题,我不知道为什么。

    6. 这是另一个我不确定但在某处提到过一次或两次的问题,如果您在类中有代码块,请尽量不要在该块中使用实例变量,再次将变量设为 __unsafe_unretained。

    就是这样,在检查了大多数这些并修复它们之后,我的所有视图都会在每次推送时调用它们的 dealloc 方法,而不是在某个奇怪的任意点。另外为了澄清这只是一个简短的清单,可以快速帮助面临相同问题的任何人,我并不声称对这里的一些概念有完全的理解,但我建议你应该这样做,因为我希望能及时。

    【讨论】:

      【解决方案2】:

      这正是 Instruments 存在的原因。运行 Leaks 工具,它会告诉您分配这些视图控制器的内容(您已经知道)以及我保留它们的其他内容(您不知道)。

      此外,您声称存在内存泄漏,但直到您运行 ObjectAlloc 工具并看到内存使用量随着重复使用而实际攀升。

      【讨论】:

      • 我确实进行了泄漏测试,这就是为什么我如此困惑以至于即使从未调用 dealloc 也没有出现泄漏。我想我应该详细说明一下我对 ARC 还很陌生,并且不确定拥有 ARC 是否会导致您的泄漏仪器过时或其他一些奇怪的行为。但是,如果我推送视图然后弹出它,没有 dealloc,但是如果我推送相同的视图然后第二次弹出它,viola,我们有 dealloc,奇怪的业务,并且没有泄漏,所以我想我应该很高兴。跨度>
      • Leak 确实适用于 ARC。但是,您所拥有的可能不是泄漏。其他东西保留了该 VC,这就是为什么您在创建 VC 的第二个实例时看到它最终释放的原因——因为保留在旧实例上的任何东西现在都会保留在新实例上。我会使用 Object Alloc 和 heapshot 来尝试看看是什么意外地保留了你的 VC。
      【解决方案3】:

      我遇到了同样的问题。

      当我从我的项目中禁用 NSZombie 选项时,它对我有用。我不知道为什么会这样。

      • 转到 ProductEdit 方案
      • 禁用 NSZombie

      【讨论】:

      • 正如我在上面向 Kendall 指出的那样,在 dealloc 方法决定现在是调用的好时机之前,我必须多次推送和弹出控制器,不过感谢您的输入。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 2012-07-18
      • 2012-02-25
      • 2012-01-31
      相关资源
      最近更新 更多