新手问题在这里。 想象一个非常基本的故事板,有2个vc(A和B)。 A嵌入在navController中。 A有一个显示图像网格的collectionView。 B正在显示点击的网格项目。如此简单的列表 - >细节。
使用IB执行所有操作,我从collectionView单元格项目ctrl-dragged到B并选择' show(例如Push)' Segue公司。
现在,当我运行应用程序并在网格中的图像上多次单击,然后在'<回'按钮,我探索内存图。 我可以看到10' B'如果我进行了10次导航,请查看控制器。
这会导致大量内存被使用,并且每次都会增长。
我发现了一些关于放松的帖子,并且弹出到root vc,但所有都在处理程序化导航。这里只是简单的故事板与IB一起完成的情况。
预期:A-> B-> A.记忆:A
现实:A-> B-> A。记忆:A,B
如何避免为那些被解雇的vc保留内存?
在A中我有:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "dreamDetail" {
let newViewController = segue.destination as! DreamDetailViewController
newViewController.dream = allDreams?[(collectionView.indexPathsForSelectedItems?.first?.item)!]
newViewController.dreams = allDreams
}
}
在B中我有:
weak var dream: DreamRealm?{
didSet {
}
}
var dreams: [DreamRealm]?{
didSet {
}
}
DreamRealm只是一个Realm模型。
class DreamRealm: Object {
@objc dynamic var filename: String? = nil
@objc dynamic var path = ""
答案 0 :(得分:1)
为避免保留被解雇的VC内存,您需要检查是否有任何保留周期。
帮助您检查您的VC是否已正确取消初始化的一步,您可以实施一个名为deinit
的方法。它是一种在VC退出并且不再存储在内存中时调用的方法。您可以打印一条消息,看看是否属实。
如果不是这样,您可能在代码中的某处有一个强引用。您需要通过使用weak
关键字或unowned
来削弱您的引用来避免它,或者只是在您不需要时删除它。
答案 1 :(得分:0)
weak
!strong
方法中发布dealloc
个对象; 有时在垃圾收集器解除分配对象之前会有一些延迟,请执行" show"并且"返回",等待~10秒,看看是否释放了更多内存。
答案 2 :(得分:0)
作为@ Arrabidas92答案的补充:
我用以下代码构建了一个保留周期:
navigationItem.reactive.rightBarButtonItems <~ user.producer.map{ $0
.map{ [weak self] user in
guard let self = self else { return [] }
我认为内部地图的[weak self]
就足够了。它不是。外部地图已经捕获了自身(将其传递给内部?)。写user.producer.map{ [weak self] $0
后,我的保留周期消失了。