在使用过渡时替换UIWindow的rootViewController似乎正在泄漏 [英] Replacing the UIWindow's rootViewController while using a transition, appears to be leaking

查看:157
本文介绍了在使用过渡时替换UIWindow的rootViewController似乎正在泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境
iOS 9.2
Xcode 7.2

我希望替换错误报告,这似乎表明iOS 8.3中存在相同的问题,并且仍然打开.

未能找到任何建议作为

的一部分

UIViewController.presentViewController(animated:completion:) 

源视图控制器被保留(很可能由解决方案

我记录了该错误报告;苹果工程公司对此没有任何回应.

我与错误报告一起提交的用于演示该问题的示例代码位于 https://github.com/adurdin/radr21404408

据我所知,该问题在当前版本的iOS中仍然存在,但我尚未进行详尽的测试.谁知道,也许9.3 beta版可以修复它? :)

在遇到此错误的应用程序中,我们一直在对大多数屏幕过渡使用自定义过渡和rootViewController替换.我还没有找到解决此泄漏的解决方案,并且由于某些原因无法轻松删除所有rootViewController操作,因此通过最小化我们使用presentViewController和好友的位置并仔细管理所需的位置来解决此问题.

我认为有可能避免该错误同时仍保留与rootViewController交换类似的功能(但尚未实现)的一种方法是让rootViewController成为自定义容器视图控制器,该控制器占据全屏并定义演示上下文.而不是交换窗口的rootViewController,我将交换此容器中的单个子视图控制器.并且因为容器定义了表示上下文,所以表示将在容器中进行,而不是交换子级.这样就可以避免泄漏.

Environment
iOS 9.2
Xcode 7.2

I'm looking to replace the UIWindow's rootViewController with an animation while also removing it from the view hierarchy as well.

class FooViewController: UIViewController
{
}

class LeakedViewController: UIViewController
{
}

Then initiate the transition in the AppDelegate simply by

    self.window!.rootViewController = LeakedViewController()

    let fooViewController = FooViewController()

    self.window!.rootViewController?.presentViewController(fooViewController, animated: true){ unowned let window = self.window!
        window.rootViewController = fooViewController
    }

Profiling this in Instruments, notice that the rootViewController is still in memory.

Also came across this bug report which seems to suggest the same issue is present in iOS 8.3 and still Open.

Haven't been able to find any references to suggest that as part of the

UIViewController.presentViewController(animated:completion:) 

the source view controller is retained (most likely by the UIPresentationController?) or if this is a bug. Notice that the UIPresentationController was first introduced in iOS 8.

If that's by design, is there an option to release the source view controller?

Using a subclass of UIPresentationController with

override func shouldPresentInFullscreen() -> Bool {
    return true
}

override func shouldRemovePresentersView() -> Bool {
    return true
}

doesn't seem make any difference. Haven't been able to locate anything else in the SDK.

Currently the only way I have found is to use a UIViewController, with a snapshot of what's currently on screen, in place of the root view controller before making the transition.

    let fooViewController = FooViewController()

    let view = self.window!.snapshotViewAfterScreenUpdates(false)
    let viewController = UIViewController()
    viewController.view.addSubview(view)

    self.window!.rootViewController = viewController
    self.window!.rootViewController?.presentViewController(dashboardViewController!, animated: true){ unowned let window = self.window!
        window.rootViewController = fooViewController
    }

It does work, tho in the console the following warning appears

Unbalanced calls to begin/end appearance transitions for <UIViewController: 0x79d991f0>.

Any ideas on the original question or the warning message appreciated.

Update

I believe I have narrowed it down to this one retain that's missing a release.

That is the possible offending call.

 0 UIKit -[UIPresentationController _presentWithAnimationController:interactionController:target:didEndSelector:]

解决方案

I logged that bug report; I have had no response from Apple engineering on it.

The sample code I submitted with the bug report demonstrating the issue is at https://github.com/adurdin/radr21404408

As far as I am aware, the issue is still present in current versions of iOS, but I have not tested exhaustively. Who knows, perhaps 9.3 beta fixes it? :)

In the application where I encountered this bug, we had been using custom transitions and rootViewController replacement for the majority of screen transitions. I have not found a solution to this leak, and because of reasons could not easily remove all the rootViewController manipulation, so instead worked around the issue by minimising where we used presentViewController and friends, and carefully managing the places where we required it.

One approach that I think has potential to avoid the bug while still retaining similar capabilities to rootViewController swapping--but have not yet implemented--is to have the rootViewController be a custom container view controller that occupies the full screen, and defines a presentation context. Instead of swapping the window's rootViewController, I would swap the single child view controller in this container. And because the container defines the presentation context, the presentations will occur from the container instead of the child being swapped. This should then avoid the leaks.

这篇关于在使用过渡时替换UIWindow的rootViewController似乎正在泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆