EditImageViewController

EditImageViewController

我有以下功能:

func attachToComment(_ data: Data, url: URL?, type: MediaType) {
    self.dismiss(animated: true, completion: nil)
    let image = UIImage(data: data)!
    model.attachmentData = data
    model.attachmentVideoURL = url
    model.attachmentType = type

    toolbar.attachImage(image, withType: type)
}

这传递给对视图控制器的引用,该引用以模态显示:
containerNavViewController.attachToComment = attachToComment
ContainerNavViewController是一个UINavigationController,其中具有容器视图控制器。这将显示相​​机,并在拍摄图像后将attachToComment函数传递给下一个视图控制器EditImageViewController。在ContainerNavViewController内部,我有以下代码:
var attachToComment: ((_ data: Data, _ url: URL?, _ type: MediaType) -> ())?
var model = CameraModel()
....

editImageViewController.attachToComment = self.attachToComment
editImageViewController.model = model
self.navigationController?.pushViewController(editImageViewController, animated: false)

在EditImageViewController内部,我有以下代码调用了闭包:
attachToComment(model.imageData, model.videoURL, model.mediaType)

然后,这将调用原始函数并关闭模式视图控制器。但是,在这些视图上未调用deinit,它们在后台非常“活跃”。我的内存泄漏在哪里,如何预防?

最佳答案

正如Dare和Sealos都暗示的那样,该问题可能是一个强大的参考周期。但是,仅在问题中提供的代码不足以导致这样的循环(因为当您关闭editImageViewController时,如果不再有对其的强引用,则释放闭包并破坏强引用循环)。

但是,一些观察结果:

  • 我无法仅使用提供的代码来复制您的强大参考周期。

    但是,如果提供editImageViewController的视图控制器对它的引用保持强烈,从而阻止了它的发布,那么我可以引发一个强大的引用周期。 editImageViewController是局部变量,还是属性?如果是属性,请将其更改为局部变量,这样可以解决问题。或者,也许其他一些东西对editImageViewController保持了强烈引用(例如,重复计时器或类似的东西)。

    您可以使用“调试内存图”工具(请参见下面的第3点)来确定哪些是editImageViewController的强引用。
  • 如果您确实要确保attachToCommentEditImageViewController对当前呈现的视图控制器没有严格的引用,我将替换为:
    editImageViewController.attachToComment = attachToComment
    

    与:
    editImageViewController.attachToComment = { [weak self] data, url, type in
        self?.attachToComment(data, url: url, type: type)
    }
    

    这是确保attachToComment中的editImageViewController闭包不维护对呈现视图控制器的强引用的最简单方法。
  • 您可能要使用Xcode 8中的“调试内存图”工具来标识EditImageViewController的所有权。例如,我举了两个例子:
  • 错误地将editImageViewController存储为呈现视图控制器的属性,而不是将其保留为局部变量(第1点);和
  • 在闭包中未使用weak模式(第2点)。

  • 当我这样做时,我得到了这样的内存图:

    ios - 通过闭包导致内存泄漏-LMLPHP

    从该图中,我不必猜测问题的根源是什么。我不仅可以看到存在强大的参考周期,而且可以看到引起问题的具体原因。但是,如果我修复以上两个问题中的一个(或两个),则此周期消失。

    关于ios - 通过闭包导致内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40408476/

    10-13 01:41