【发布时间】:2019-08-18 14:31:39
【问题描述】:
我创建了一个导航,它推送一个视图控制器,其中包含一个图像视图和一个按钮,每次点击按钮时都会添加相同的视图控制器。每次点击后,内存都会增长,每次返回后,尽管调用了deinit,但内存不会被释放。代码中没有任何内容指向内存泄漏是我遗漏了什么吗?谢谢?
class ViewController: UIViewController {
lazy var nextButton:UIButton? = {
let button = UIButton(type: .roundedRect)
button.setTitle("Next", for: .normal)
button.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = UIColor.red
return button
}()
lazy var imageView:UIImageView? = {
let image = #imageLiteral(resourceName: "DJI_0014")
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
guard let imageView = self.imageView, let nextButton = self.nextButton else{
print("imageView, nextButton are nil")
return
}
self.view.backgroundColor = UIColor.white
self.view.addSubview(imageView)
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo:self.view.topAnchor),
imageView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
imageView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
imageView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)])
view.addSubview(nextButton)
NSLayoutConstraint.activate([nextButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
nextButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0),nextButton.heightAnchor.constraint(equalToConstant: 200),nextButton.widthAnchor.constraint(equalToConstant: 200)])
}
@objc func nextButtonTapped(){
print("next button tapped")
self.navigationController?.pushViewController(ViewController(), animated: true)
}
deinit {
print("view controller is deinitialized")
}
}
我查看了下面列出的其他问题并尝试采纳他们的建议,但似乎都没有帮助
Navigation arc memory not released
【问题讨论】:
-
使用真机而不是模拟器运行长时间测试,例如100次push和pop,你会发现它有一个cap memory并且稳定在18M以下(这取决于图像的大小。) .
-
@E.Coms 感谢您花时间运行它并浏览它。我一直在 iPhone X 和 iPhone 6s Plus 上进行所有测试。我也怀疑该图像,因此我在测试中删除了该图像。在连续运行大约 20-30 次推送和 20-30 次连续弹出后,内存似乎在内存调试器中像一座山一样增长,尤其是在第一次弹出后出现峰值。探查器中报告了泄漏,但我读过这些可能会产生误导,并且我查看了内存图但没有发现任何有用的信息,这是一个非常奇怪的现象。
-
我相信你的项目中有更多的代码和资源。这是一种正常情况,因为它将由系统处理,例如缓存和动画优化。这里提供的代码应该没问题。如果没有其他错误和泄漏,它将在 40-50M 左右达到峰值。除非有任何泄漏,否则您可能会忽略。也可以考虑及时popToRoot。不断推送这么多 vcs 是一种罕见的情况。也许10层就足够大了。您可以更改 VC 的内容,而不是 vc 它自己。
-
@E.Coms 我添加了一个指向完整项目存储库的链接,以便您自己查看github.com/TheRedCamaro30/Leaky-Navigation-Controller。我没有理由想到为什么当用户从 ViewController 滑出时,在内存被释放的情况下,视图的行为不应该像预期的那样。从理论上讲,只要负责任地处理解除分配,用户就应该能够向导航控制器添加大量视图。
-
如我所说,如果隐藏导航栏并关闭所有动画。最大内存22M左右,加起来100层+没问题。如果您打开动画并且导航栏显示带有后退按钮,则最大值应为 35M。峰值的原因是为动画控制器和相关节省了一些空间。有一次这样的跳跃,再也不会发生了。
标签: swift xcode memory-leaks uinavigationcontroller automatic-ref-counting