【问题标题】:Controller doesn't deinit after present new controller控制器在出现新控制器后不会取消初始化
【发布时间】:2018-06-12 14:54:42
【问题描述】:

我有一个FakeSplashController,它执行一些网络请求,然后打开WelcomeViewController。当我在WelcomeViewController 中查看内存图时,我看到SplashViewController 仍然在那里。我在FakeSplashController 中调用deinit 函数来检查它是否正在拒绝但它没有调用它。可能是什么问题?

我在WelcomeViewController 时在内存中看到的内容:

FakeSplashController:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    setupUI()
    networkRequests()

}

func networkRequests(){

    AppInitService().initAppRequest { [](result) in
        switch result{
        case .success(_):
            self.startAnimation()
            return
        case .error(let error):
            UIControlUtil.showErrorMessage(title: error.title, message: error.message, closeButton: true)
            return
        }
    }
}

func openApp(){
        let loginController = WelcomeViewController()
    self.present(loginController, animated: true)
}

func startAnimation(){
    UIView.animate(withDuration: 0.8, animations: {
        self.logoImage.frame.origin.x -= 100
    }, completion: nil)
    UIView.animate(withDuration: 1,delay: 0.3,animations: {
        self.textLogo.alpha = 1
        self.textLogo.frame.origin.x += 50
    }, completion: { _ in
        self.openApp()
    })
}

deinit {
    print("Splash Deinited")
}

编辑:正如我在下面的帖子中提到的那样,有人提到了这一点;

除非您正在做一些非常专业的事情,否则您不需要在 Swift 中取消初始化对象。它会在引用计数变为 0 时自动调用。如果确实需要,您应该可以通过 AppDelegate 设置窗口的 rootViewController。

所以我不需要把它当作一个问题吗? Best way to deinit Initial view controller?

【问题讨论】:

  • 自从您提出WelcomeViewController 后,您希望如何释放启动画面?
  • 我想我不确定是否需要。因为我和splash没有任何关系了。
  • 一个视图控制器在你展示另一个视图控制器时不会被释放;它仍然生活在新的之下。事实上,如果你关闭WelcomeViewController,你会再次看到飞溅
  • @RicoCrescenzio 是对的,你也可以看到,当你打开 Xcode 的 ViewDebugger 时。在 ViewDebugger 中向两侧滚动一点,您将看到,在 WelcomeViewController 后面是 SplashViewController。当您关闭 WelcomeViewController 时,您也会看到 SplashViewController。

标签: ios swift uiviewcontroller


【解决方案1】:

正如我在评论中所说,您的代码没有什么奇怪的,这就是 iOS 框架的工作原理;视图控制器没有被释放,因为它仍然是当前窗口的rootViewController。 我不认为非常需要释放它,但如果你真的需要这样做,一个解决方案可能是用你的WelcomeViewController 替换rootViewController。通过替换它,启动屏幕的引用计数将变为 0,并将被释放。 类似的东西

guard let window = UIApplication.shared.keyWindow else {
    return
}
self.dismiss(animated: false, completion: nil)
window.rootViewController = WelcomeViewController()

这个问题是没有动画(但是你也可以实现动画,只是找到如何动画rootViewController更改)

【讨论】:

  • 再问一个问题。例如,我有一个 ViewController 存储 10mb 的内存。当我没有释放它时(就像在我的代码中做的那样),它仍然会在内存上使用 10 mb 还是会被释放?我不确定需要为 splashController 使用哪一个
  • 它将是活着的,因此它将继续使用 10 mb 直到其引用计数达到 0。
  • 所以最好将您的代码用于 SplashViewController 甚至 WelcomeViewController 因为直到用户注销才能看到它?
  • 也许在内存使用方面会更好,但我不会担心 2 个简单的视图控制器;那么我将不得不重新实现推送动画以使导航保持一致
  • 嗯,也许你会是真的。一种解决方案是保留它,另一种是为推送制作自定义动画?如果有更多关于保留与取消它的信息,那就太好了。
猜你喜欢
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 2013-07-04
  • 2019-09-10
  • 2020-09-23
  • 2019-10-13
相关资源
最近更新 更多