切换UIWindow的rootViewController时导致的内存泄漏

一、切换rootViewController之前,present某一控制器

self.window = UIWindow.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
self.window?.rootViewController = UINavigationController(rootViewController: ViewControllerA())
self.window?.makeKeyAndVisible()
self.present(ViewControllerB(), animated: true, completion: nil)

在切换rootViewController的时候,必须先dismiss当前控制器,否则将产生内存泄漏:

self.dismiss(animated: false) {
    let window = UIApplication.shared.keyWindow
    window?.rootViewController = UINavigationController(rootViewController: ViewControllerA())
    window?.makeKeyAndVisible()
}

原因分析:因为ViewControllerA present ViewControllerB,即ViewControllerA引用ViewControllerB,自动引用计数+1。在切换rootViewController之后,window的rootViewController不再引用UINavigationController,UINavigationController的计数器为0,随后被释放,与此同时栈内的ViewControllerA也会被释放。但是,ViewControllerA始终没有release ViewControllerB,导致ViewControllerB的计数器始终不为0,从而导致内存泄漏。

二、切换rootViewController之前,push某一控制器

self.navigationController?.pushViewController(ViewControllerB(), animated: true)

在切换rootViewController的时候,直接切换即可,不用担心内存泄漏:

let window = UIApplication.shared.keyWindow
window?.rootViewController = UINavigationController(rootViewController: ViewControllerA())
window?.makeKeyAndVisible()

原因分析:因为ViewControllerA push ViewControllerB,它们均被压入到UINavigationController栈中。在切换rootViewController之后,window的rootViewController不再引用UINavigationController,UINavigationController的计数器为0,随后被释放,与此同时栈内的ViewControllerA、ViewControllerB也都会被释放。


最后,在切换window的rootViewController时候,还需要注意切换前后的window是否是同一个window,否则也会造成内存泄漏,所以建议在项目中有切换rootViewController的地方都看一下视图的层级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值