ios – 使用自适应弹出窗口并将导航包裹在导航控制器中会导致内存泄漏

假设我有一个视图控制器,当点击一个按钮时,我使用自适应弹出窗口显示.现在在某些情况下,我可能想要将目的地视图控制器包含在(例如)导航控制器中.所以,我将自己设置为popoverPresentationController的委托代理,并实现presentationController:viewControllerForAdaptivePresentationStyle:method.

但是我注意到一些奇怪的东西:在某些情况下,对象没有被释放.如果在前面提及的方法中,我将导出的控件中的所显示的视图控件:

func presentationController(controller: UIPresentationController,viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
    return UINavigationController(rootViewController: controller.presentedViewController)
}

在关闭导航控制器被释放,但是所呈现的视图控制器保持分配.

相比之下,如果通过自适应弹出窗口直接显示导航控制器,则关闭导航控制器及其包含的详细信息控制器可以正确解除分配.

为了演示,请参考这个测试项目(Swift):https://github.com/djbe/AdaptivePopoverSegue-Test

在导航控制器中动态包装时,我们得到了什么(点击“Popover,导航自动添加”按钮):

--- Showing details ---
Loaded details view controller (0x7fab31632b70)
Loaded navigation controller (0x7fab32815600)
Deinit navigation controller (0x7fab32815600)

您可以看到,细节视图控制器永远不会被释放.

我查看了presentationController的文档:viewControllerForAdaptivePresentationStyle:但没有具体提及所有权,强大的保留等…
我尝试使用“分配工具”工具,但是在这种(简单)的情况下涉及到很多保留/释放,我无法直接找到问题.

有没有人遇到这个问题?或者你有什么想法如何解决这个问题?

由@TomSwift如下所述,由于控制器和segue之间的循环引用,存在一个错误.解决这个问题的唯一方法是将目标控制器包装在导航控制器中,是通过在segue(custom)的init方法中进行包装.

我已经在Github上更新了我的示例代码,以展示如何使用@Vasily所提到的解决方案实现这一点,但仍然允许使用协议进行动态包装行为,而不使用使用NSUserDefaults的恶意

解决方法

.

解决方法

您需要创建自定义的UIStoryboardSegue类并覆盖init函数.

样品:

class StoryboardSegue: UIStoryboardSegue {

override init(identifier: String?,source: UIViewController,destination: UIViewController) {
    super.init(identifier: identifier,source: source,destination: NavigationController(rootViewController: destination))
}
}

Main.storyboard

结果

以上是来客网为你收集整理的ios – 使用自适应弹出窗口并将导航包裹在导航控制器中会导致内存泄漏全部内容,希望文章能够帮你解决ios – 使用自适应弹出窗口并将导航包裹在导航控制器中会导致内存泄漏所遇到的程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。