iOS - 切换rootViewController时,销毁之前的控制器

本文介绍iOS中切换根控制器时如何避免内存泄漏,包括通过push和present两种方式切换控制器时的具体处理方法,以及如何正确使用dismiss确保旧控制器被销毁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.iOS在切换根控制器时,如何销毁之前的控制器?(切换rootViewController时注意的内存泄漏)

首先、在iOS的ARC机制下,任何对象,当没有其他对象对他进行强引用时,都会被自动释放。

而控制器的切换主要为两种方式 push和present modally。


1.0 push出来的子控制器,导航栏控制器会对该子控制器进行强引用(本质就是入栈,在入栈的过程中,可能不止是导航栏控制器对子控制器有强引用)

其中 push 对应着 pop 则控制器会被销毁。其push的本质是入栈,所有的子控制器放在数组中,先进后出,如果导航栏作为根控制器。此时需要更该根控制器,不管push了多少子控制器入栈了。其最后只需要在当前显示的子控制器中对根控制器重新赋值即可。即原先的导航栏控制器没有对象强引用它,它会被释放,其所有的子控制器自然都会被释放了(前提是你本身代码不存在其他内存泄漏)

                  UIApplication.shared.keyWindow?.rootViewController = newRootVC

1.1 谁来调用这消失presented VC的这个方法:正确的做法是“谁污染谁治理”,对于弹出模态,系统指定了销毁的方法dismiss,其中动画效果暂时关闭(原因在后面)

                    dismiss(animated: false, completion: nil)

举例: 在我们的项目中假如需要在firstVC2控制器进行根控制器的切换。firstVC2控制器是这样来的:

ViewController  push ---->firstVC1  present--->firstVC2 。则如何在firstVC2中切换根控制器,并同时销毁之前的控制器。则必须先dismiss掉 firstVC2 。实现如下:

dismiss(animated: false) {

UIApplication.shared.keyWindow?.rootViewController = newRootVC

}

分析:如果不dismiss掉 firstVC2,则firstVC2不会被释放。firstVC2无法释放,必然导致firstVC1无法释放,而栈顶元素无法被释放,栈顶下面的控制器都无法释放。

 

注意:

1.动画状态必须关闭,根控制器的切换与dismisse的动画同时进行会给用户带来较差的体验效果。

2在项目开发中,只要有present出来的控制器,一定要有对应的dismiss,否则项目中会存在无法估量的bug

demo的代码:https://github.com/ZuoCaiSong/TestRootVC

 

 

转载于:https://www.cnblogs.com/junhuawang/p/8528403.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值