iOS 解决设置rootViewController 内存不释放问题

1,924 阅读1分钟

keyWindow 设置新的 rootViewController时如果之前有模态的视图控制器,那么需要调用dismiss方法,并在complete回调中设置rootViewController

self.dismiss(animated: false) {
    UIApplication.shared.keyWindow?.rootViewController = NewViewController()
}

模态了很多层怎么办?

下面提供一个快捷查找所有模态控制器的方法

    func safeSet(keyWindow rootViewController: UIViewController) {
        var tempArr = [UIViewController]()
        var tempVc = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController
        var flag =  tempVc != nil
        
        while flag {
            tempArr.append(tempVc!)
            tempVc = tempVc?.presentedViewController
            flag = tempVc != nil
        }
        for (index, item) in tempArr.reversed().enumerated() {
            if index == tempArr.count - 1 {
                item.dismiss(animated: false) {
                    UIApplication.shared.keyWindow?.rootViewController = rootViewController
                }
            } else {
                item.dismiss(animated: false, completion: nil)
            }
        }
    }

iOS13 苹果修复了这个问题

是的如果你只支持 iOS13 那么请忽略上面的那个问题。 给我们的代码加上版本判断

    func safeSet(keyWindow rootViewController: UIViewController) {
        if #available(iOS 13.0, *) {
            UIApplication.shared.windows.first?.rootViewController = rootViewController
        } else {
            var tempArr = [UIViewController]()
            var tempVc = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController
            var flag =  tempVc != nil
            
            while flag {
                tempArr.append(tempVc!)
                tempVc = tempVc?.presentedViewController
                flag = tempVc != nil
            }
            for (index, item) in tempArr.reversed().enumerated() {
                if index == tempArr.count - 1 {
                    item.dismiss(animated: false) {
                        UIApplication.shared.keyWindow?.rootViewController = rootViewController
                    }
                } else {
                    item.dismiss(animated: false, completion: nil)
                }
            }
        }

    }