【问题标题】:presentViewController memory leakpresentViewController 内存泄漏
【发布时间】:2023-04-10 16:54:01
【问题描述】:

我刚刚开始 iOS 编程,正在尝试以编程方式切换视图控制器(即从一个视图切换到另一个视图)。我知道呈现下一个视图控制器的视图控制器需要在呈现另一个视图控制器后被释放,但我似乎无法得到任何有效的东西。在展示下一个控制器后,我尝试关闭控制器,但仍然出现内存泄漏。

所以我在ViewControllerA 中有这个代码:

- (void) switchViews {
    [self presentViewController:[[ViewControllerB alloc] init] animated:NO completion:nil];
}

这个在ViewControllerB:

- (void) switchViews {
    [self presentViewController:[[ViewControllerA alloc] init] animated:NO completion:nil];
}

视图中的按钮触发这些事件,基本上它们只是从一个视图切换到另一个视图。

那么如何来回切换视图以免造成内存泄漏?另外,我使用的是 ARC。

【问题讨论】:

  • 这不是答案,但在 Objective-c 中,BOOL 类型需要YESNO 而不是truefalse
  • 看起来你也不是在解雇旧的 VC,只是不断地展示它们。你会在某个地方解雇他们吗?
  • 有泄漏是因为每次调用'switchViews'方法时,都是分配内存并创建一个新的viewcontrollerA/B,而不是检查内存中是否已经存在这样的控制器并重用它们。跨度>
  • @danielbeard 啊谢谢你让我知道 BOOL 的事情,我刚开始使用 Objective-C。我已经更新了问题。
  • 好吧,既然 B 来自 A,不用presentViewController 回到 A,只需在 VC B 中使用 [self dismissViewControllerAnimated:NO completion:nil]; 回到 A。这样你就不会一直重新创建在一个无限循环中。

标签: ios uiviewcontroller


【解决方案1】:

基本上,您在上面的代码中所做的是创建 ViewController A,然后是 ViewControllerB,然后是另一个 ViewController A,然后是另一个 ViewController B,然后是另一个 ViewController A,然后是另一个 ViewController B。

你应该做的是从 ViewController A 开始,创建 ViewController B,然后回到 ViewController A,关闭 ViewController B。

阅读this blog,了解如何按照我解释的简单方法进行操作。

现在,使用这种方法有可能会导致一些问题,而且它们很可能只会在您想要做的不仅仅是关闭当前的 ViewController 多一点的时候发生。事实上,Apple 确实在他们的文档中声明:

"当需要关闭呈现的视图控制器时,首选的方法是让呈现的视图控制器解除它。换句话说,只要有可能,呈现视图控制器的同一个视图控制器也应该负责解除虽然有几种技术可以通知呈现视图控制器其呈现的视图控制器应该被解除,但首选技术是委托。”

现在,正如@LeoNatan 的回答所说,使用[self dismissViewControllerAnimated:completion: 这样做可能是一种不好的做法。上面这段话就是为什么,我相信,他说这是个坏主意。

学习如何以两种方式做到这一点确实是一种很好的做法。虽然我的回答是快速的方法,但它也有点脏。

【讨论】:

  • 感谢您的博文。很棒的信息。
  • @CaptJak 当有多个视图控制器(如 A、B、C、D、E、F)时会发生什么。所以呈现流程从A开始,B已经呈现然后C。然后从F我们需要显示A!最好的做法是什么???
  • @KaranAlangat,要跳回到几个 VC,您可以使用 unwind segue。我有同样的问题,我发布了here。看答案。它是 Objective-C,但它仍然有效。
  • @CaptJak 我没有使用转场,因为屏幕位于不同的故事板中???
  • @KaranAlangat:确保您使用导航控制器,然后通读 this part of the Apple Docs 以找到可行的方法。如果您无法弄清楚,请在 SO 上搜索答案,或发布另一个问题。我们评论的那个已经快 3 岁了。
【解决方案2】:

这对你来说应该是一个很好的练习,学习 Objective C 和设计模式。

使用“viewControllerBDidClose:”方法创建一个 ViewControllerBDelegate 协议。在 ViewControllerB 中创建一个名为“delegate”的属性。现在,在 vcA 中创建 vcB 后,将委托对象设置为 vcA。现在,当您想从 vcB 回到 vcA 时,您应该通知代理您希望关闭 vcB。然后 vcA 会“dismissViewController:animated:” vcB。

这种设计模式称为委托,并在对象与其委托之间提供双向“对话”。委托使用公共 API 与对象“对话”,而对象使用委托协议与其委托“对话”。

在 cmets 中,有人建议您从自身中解散 vcB。这是一种不好的做法,从不推荐。谁提出了一个视图控制器,谁就应该把它解散。通过委派的方式,您通知演示者演示已完成,演示者应解除演示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2013-01-20
    • 2011-10-31
    • 2019-08-10
    • 2013-06-24
    • 2011-03-22
    • 2015-04-20
    相关资源
    最近更新 更多