iOS swift:Deinit一个孩子View Controller
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS swift:Deinit一个孩子View Controller相关的知识,希望对你有一定的参考价值。
我在ViewController中有一个UITabBar。选择标签栏项目我添加了不同的子视图控制器。并删除其他人。
但我从来没有在控制台上看到deint日志,只有viewWillDisappear ..
我如何确定deint子视图控制器以节省内存?
这是我创建子控制器的方式:
private lazy var lotteryViewController: LotteryViewController = {
// Load Storyboard
let storyboard = UIStoryboard(name: "TrophyRoom", bundle: Bundle.main)
// Instantiate View Controller
var viewController = storyboard.instantiateViewController(withIdentifier: "LotteryViewController") as! LotteryViewController
// Add View Controller as Child View Controller
self.add(asChildViewController: viewController)
return viewController
}()
添加子控制器:
private func add(asChildViewController viewController: UIViewController) {
// Add Child View Controller
addChildViewController(viewController)
// Add Child View as Subview
containerView.addSubview(viewController.view)
// Configure Child View
viewController.view.frame = containerView.bounds
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Notify Child View Controller
viewController.didMove(toParentViewController: self)
}
从父viewController调用的remove方法:
private func remove(asChildViewController viewController: UIViewController) {
// Notify Child View Controller
viewController.willMove(toParentViewController: nil)
// Remove Child View From Superview
viewController.view.removeFromSuperview()
// Notify Child View Controller
viewController.removeFromParentViewController()
}
子控制器的日志方法:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("Sessions View Controller Will Appear")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("Sessions View Controller Will Disappear")
}
deinit {
NotificationCenter.default.removeObserver(self)
// Log if a view controller is being deinited
print("\nDeinit: \(self.description)\n")
}
类实例内存管理通过保留引用的计数来工作。 deinit
的意思是“这个物体即将不存在,因为它没有更多的保留参考”。
当您添加子视图控制器和删除子视图控制器时,您正在正确地进行父子“跳舞”。所以从这个角度来看一切都很好。当你调用viewController.removeFromParentViewController
时,保留对它的引用肯定会消失,即父子保留引用(childControllers
数组,它已经删除并释放了孩子)。
但这并不意味着所有保留参考文献都会消失。事实上,没有被称为deinit
的事实表明存在其他一些保留参考。你现在要做的就是找出那个参考资料。但事实上,你似乎向我们展示了它是什么:
private lazy var lotteryViewController: LotteryViewController = {
let storyboard = UIStoryboard(name: "TrophyRoom", bundle: Bundle.main)
var viewController = storyboard.instantiateViewController(withIdentifier: "LotteryViewController") as! LotteryViewController
self.add(asChildViewController: viewController)
return viewController
}()
lotteryViewController
是对子视图控制器的强大(保留)引用。因此,即使在您将其作为孩子移除之后,它也会使视图控制器保持活动状态。
所以你的架构存在一个弱点(或者至少是一个意想不到的结果)(我的意思是你好奇地使用带有定义和调用初始化器的lazy var
实例属性)。创建子视图控制器的方法是实例化视图控制器,将其作为子视图传递给父视图,然后释放视图控制器,以便对它的唯一引用是父视图。 (如果你需要随后引用孩子,你总是可以通过父母来获得它。)你没有这样做,所以当孩子从父母那里移除时你不会得到deinit
。
以上是关于iOS swift:Deinit一个孩子View Controller的主要内容,如果未能解决你的问题,请参考以下文章
swift playground / deinit 中的内存泄漏未一致调用
是否应该重写 deinit 以删除 Swift 中的观察者?
为 NSNotificationCenter = Swift deinit() 调用 .removeObserver 的正确位置?