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

前端之家收集整理的这篇文章主要介绍了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相关文章