Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 导航控制器后退按钮未释放控制器的内存_Ios_Swift_Memory Leaks_Uiviewcontroller - Fatal编程技术网

Ios 导航控制器后退按钮未释放控制器的内存

Ios 导航控制器后退按钮未释放控制器的内存,ios,swift,memory-leaks,uiviewcontroller,Ios,Swift,Memory Leaks,Uiviewcontroller,这里是新手问题。 想象一个有两个vc(a和B)的非常基本的故事板。 导航控制器中嵌入了一个导航控制器。A有一个collectionView,显示图像网格。B以大字体显示单击的网格项。所以简单的列表->细节 使用IB执行所有操作时,我按ctrl键从collectionView单元格项拖动到B,并选择“显示(例如推)”序列 现在,当我运行应用程序并多次单击网格中的图像,然后单击“B->A。内存:A 现实:A->B->A。记忆:A,B 我如何避免为那些被解雇的vc保留内存 在一份声明中,我: over

这里是新手问题。 想象一个有两个vc(a和B)的非常基本的故事板。 导航控制器中嵌入了一个导航控制器。A有一个collectionView,显示图像网格。B以大字体显示单击的网格项。所以简单的列表->细节

使用IB执行所有操作时,我按ctrl键从collectionView单元格项拖动到B,并选择“显示(例如推)”序列

现在,当我运行应用程序并多次单击网格中的图像,然后单击“ 这会导致大量内存被使用,并且每次都会增加

我发现一些帖子谈到了“放松”和“跳转到根目录vc”,但都是关于程序导航的。下面是用IB完成的简单故事板的例子

预期的:A->B->A。内存:A

现实:A->B->A。记忆:A,B

我如何避免为那些被解雇的vc保留内存

在一份声明中,我:

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只是一个领域模型

class DreamRealm: Object {

@objc dynamic var filename: String? = nil
@objc dynamic var path = ""

为了避免保留被撤销的VC内存,您需要检查是否存在任何保留周期

为了帮助您检查VCs是否正确反初始化,您可以实施一个名为
deinit
的方法。当你的VC是Denit并且不再在内存中时,就会调用这个方法。你可以打印一条消息,看看是否是这样

如果不是这样,您的代码中可能有一个强引用。您需要通过使用
weak
关键字或
unowned
削弱您的引用来避免它,或者如果您不需要它,就删除它

  • 所有带有UI元素的IB连接(在视图控制器中)都必须
    
    
  • 尝试在
    dealloc
    方法中释放
    strong
    对象
    有时,在垃圾收集器释放对象之前会有一些延迟,请执行“显示”和“返回”,等待10秒钟,看看是否释放了更多内存。

    作为@Arrabidas92答案的补充:

    • 注意双层嵌套块
    我用以下代码构建了一个retain循环:

    navigationItem.reactive.rightBarButtonItems <~ user.producer.map{ $0
        .map{ [weak self] user in
            guard let self = self else { return [] }
    

    navigationItem.reactive.RightBarButtonims在您的代码中的其他地方a->B和B->a之间是否存在强引用?您是如何从B导航到a的?@ReinierMelian正如我在描述中所说的,只需按下导航控制器上的后退按钮。没有自定义代码。@TusharSharma看起来像是。但我刚刚用Instruments/Leaks工具分析了这个应用程序,它在进行导航时显示了所有绿色检查。我试图在新项目中复制这个问题,Denit被调用。然而,在我的应用程序上它不是。然后可能有一个强引用。我不明白为什么仪器/泄漏显示所有绿色检查..当导航a到B时,我在prepareForSegue中“传递”了2个对象。1是一个自定义类。另一个是自定义类的数组。第一个我可以做得很弱,但后一个我做不到“可能只应用于类和类绑定协议类型,而不是…”您能为prepareForSegue发布一些代码吗?它将帮助我们确定问题并帮助您。还有自定义类的代码。我刚刚发现了问题。看起来原因是图像幻灯片播客。因为当我注释掉所有对它的引用时,我调用了deninit中的print方法。干得好有时外部API有奇怪的行为。