【问题标题】:Swapping rootViewController on UIWindow does not deallocate view controller在 UIWindow 上交换 rootViewController 不会释放视图控制器
【发布时间】:2019-10-07 01:33:29
【问题描述】:

如果您将rootViewController 换成UIWindow,例如,以显示一个登录窗口,如果rootViewController 已显示(模态)视图控制器,那些已显示的视图控制器,可能还有旧的rootViewController 不会被释放。

self.window.rootViewController = newViewController

【问题讨论】:

    标签: ios uikit


    【解决方案1】:

    UIKit 对象通常在内部使用autorelease 发布。这意味着他们不能保证立即被释放。但是,您可以通过包装应该使用自动释放池释放对象的函数来强制解除分配。

    autoreleasepool {
        self.window.rootViewController = newViewController
    }
    

    有关自动释放和自动释放池的详细说明,请查看this answer

    【讨论】:

      【解决方案2】:

      您必须始终在换出 rootViewController 时关闭所有 modals,否则会有一个保留循环。

      if window?.rootViewController.presentedViewController != nil {
          window?.rootViewController.dismiss?(animated: false) {
              window?.rootViewController = newViewController
          }
      }
      else {
          window?.rootViewController.dismiss?(animated: false)
          window?.rootViewController = newViewController
      }
      

      如果你想做一个漂亮的过渡,你总是可以用动画包裹它:

      func transition() {
          if window?.rootViewController.presentedViewController != nil {
              window?.rootViewController.dismiss?(animated: false) {
                  window?.rootViewController = newViewController
              }
          }
          else {
              window?.rootViewController.dismiss?(animated: false)
              window?.rootViewController = newViewController
          }
      }
      
      UIView.transition(with: window!,
                        duration: 0.3,
                        options: .transitionCrossDissolve,
                        animations: transition)
      

      【讨论】:

      • 更好的是,不要那样做。你不应该改变根视图控制器。
      • 这基本上是对的。为了安全删除,这里有一点:self.myWindow?.rootViewController?.dismiss(animated: false, completion: { self.myWindow?.rootViewController = newViewController })
      • @matt 我在文档中没有看到任何内容表明不鼓励更改窗口的根视图控制器,它是一个读写属性。比在现有根视图控制器中处理现有视图层次结构或在“基础”根视图控制器中使用视图控制器包含安全得多。
      • @E.Coms 谢谢,没错!我假设即使没有提供任何模态,也会调用完成。否则你需要检查presentedViewController,我稍后会做一些测试
      • 我显然不同意。
      猜你喜欢
      • 2014-10-04
      • 1970-01-01
      • 2014-11-17
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多