Swift 显示模式视图并取消它时内存泄漏

Swift 显示模式视图并取消它时内存泄漏,swift,memory-leaks,Swift,Memory Leaks,当AVExportSession完成导出后,我让我的应用程序显示一个模式视图,显示视频和一组图像。取消模式视图,并使其反复显示,会显示不断增长的内存增加。我怀疑可能会出现一个强大的参考循环 我正在模态视图(manageCaptureVC)上设置必需的变量。fileURL是一个全局变量,manageCaptureVC可以从中读取以获取视频。当模式视图被取消时,将基于该URL删除视频。泄漏的大小取决于在模式视图中捕获和显示的介质的大小 我用过仪器。不幸的是,它从未指向我的任何函数。它显示显示汇编语言

当AVExportSession完成导出后,我让我的应用程序显示一个模式视图,显示视频和一组图像。取消模式视图,并使其反复显示,会显示不断增长的内存增加。我怀疑可能会出现一个强大的参考循环

我正在模态视图(manageCaptureVC)上设置必需的变量。fileURL是一个全局变量,manageCaptureVC可以从中读取以获取视频。当模式视图被取消时,将基于该URL删除视频。泄漏的大小取决于在模式视图中捕获和显示的介质的大小


我用过仪器。不幸的是,它从未指向我的任何函数。它显示显示汇编语言的内存地址。我也在使用一个设备

这是我的泄漏仪器在我显示和关闭视图时的屏幕截图,仪器指示泄漏:

有什么明显的东西会导致我的案子泄露吗

显示模式视图(manageCaptureVC)

驳回这一观点:

func goBackTask(){

    // turn off manage capture tutorial if needed
    if debug_ManageCaptureTutorialModeOn {
        debug_ManageCaptureTutorialModeOn = false
        delegate?.resetFiltersToPrime()
    }
    // no longer ignore interface orientation
    ignoreSelectedInterfaceOrientation = false

    // remove observer for the application becoming active in this view
    NotificationCenter.default.removeObserver(self,
                                              name: UIApplication.didBecomeActiveNotification,
                                              object: nil)

    if let videoEndedObs = self.videoEndedObserver {
        NotificationCenter.default.removeObserver(videoEndedObs)
    }

    // invalidate thumb timer
    thumbColorTimer.invalidate()

    // empty UIImages
    uiImages.removeAll()

    // delete video
    let fileManagement = FileManagement()
    fileManagement.checkForAndDeleteFile()

    let group = DispatchGroup()
    group.enter()

    DispatchQueue.main.async {
        self.enableButtons(enabled:false)
        if let p = self.player, let pl = self.playerLayer {
            p.pause()
            pl.removeObserver(self, forKeyPath: "videoRect")
            pl.removeFromSuperlayer()
            p.replaceCurrentItem(with: nil)
        }

        group.leave()
    }

    let group2 = DispatchGroup()

    group.notify(queue: .main) {

        group2.enter()

        DispatchQueue.main.async {
            self.enableButtons(enabled:true)
            group2.leave()
        }

    }

    group2.notify(queue: .main) {
        self.dismiss(animated: true)
    }

}

我也遇到了这个问题。我花了好几天才找到它。 将modalPresentationStyle设置为.fullScreen导致视图控制器未被释放。我能够在一个简单的例子中重现这一点。 我通过将modalPresentationStyle设置为.currentContext解决了这个问题。
没有一个工具能够识别这个保留周期——我猜是因为它是在低级的苹果代码中。

真的没有必要要求人类检查你的代码。如果出现泄漏,仪器将告诉您泄漏的原因,并向您显示导致泄漏的原因。还要记住,调试模式下模拟器上的内存管理并不能指示释放模式下设备上会发生什么。我使用了泄漏仪器。不幸的是,它从未指向我的任何函数。它显示显示汇编语言的内存地址。我还使用了一个设备。使用带有保留跟踪功能的分配工具查看泄漏的内容和原因。我有。它没有显示任何有用的东西。我可以用泄漏或分配工具的截图更新帖子。
func goBackTask(){

    // turn off manage capture tutorial if needed
    if debug_ManageCaptureTutorialModeOn {
        debug_ManageCaptureTutorialModeOn = false
        delegate?.resetFiltersToPrime()
    }
    // no longer ignore interface orientation
    ignoreSelectedInterfaceOrientation = false

    // remove observer for the application becoming active in this view
    NotificationCenter.default.removeObserver(self,
                                              name: UIApplication.didBecomeActiveNotification,
                                              object: nil)

    if let videoEndedObs = self.videoEndedObserver {
        NotificationCenter.default.removeObserver(videoEndedObs)
    }

    // invalidate thumb timer
    thumbColorTimer.invalidate()

    // empty UIImages
    uiImages.removeAll()

    // delete video
    let fileManagement = FileManagement()
    fileManagement.checkForAndDeleteFile()

    let group = DispatchGroup()
    group.enter()

    DispatchQueue.main.async {
        self.enableButtons(enabled:false)
        if let p = self.player, let pl = self.playerLayer {
            p.pause()
            pl.removeObserver(self, forKeyPath: "videoRect")
            pl.removeFromSuperlayer()
            p.replaceCurrentItem(with: nil)
        }

        group.leave()
    }

    let group2 = DispatchGroup()

    group.notify(queue: .main) {

        group2.enter()

        DispatchQueue.main.async {
            self.enableButtons(enabled:true)
            group2.leave()
        }

    }

    group2.notify(queue: .main) {
        self.dismiss(animated: true)
    }

}