ios - swift 内存泄露怎么办?

标签 ios objective-c swift memory-management

我是 ios 开发的新手,我想了解内存泄漏是如何在 swiftObjective-C 中发生的,谁能用小例子解释一下?

谢谢

最佳答案

小例子:

class A {
    var b: B!

    deinit {
        print("deinit of A")
    }
}

class B {
    var a: A!

    deinit {
        print("deinit of B")
    }
}

do {
    let a = A()
    let b = B()
    a.b = b
    b.a = a
}

如果您运行此代码(可能在 Playground 中),它不会打印任何内容。这意味着 deinit 从未调用过这两个对象,它们只是泄漏了。

但是,如果您将其中一个属性声明为 weak:

class A {
    weak var b: B!

    deinit {
        print("deinit of A")
    }
}

然后 deinit 将被调用,您将在控制台中看到消息。

编辑:添加闭包示例

考虑这个例子:

class C {
    var f: (Void -> Void)!

    deinit {
        print("deinit for C")
    }
}

do {
    let c = C()
    c.f = {
        print(c)
    }
}

c 捕获 ff 捕获 c。所以我们有内存泄漏。

要处理闭包中的泄漏,您有 2 个选择——声明捕获的对象是 weakunowned。像这样:

do {
    let c = C()
    c.f = { [weak c] in
        print(c)
    }
}

基本上,如果调用闭包时对象可能不存在并变为nil,您将使用weak;但如果您确定此时对象仍然存在,请改用 unowned

在我将 c 声明为闭包内的 weak 后,会打印“deinit for C”——这意味着一切都已成功解除分配。

这对开发者来说意味着什么?

几乎所有时候你都不必担心内存管理。它会自动为您完成。对象只在您需要时存在,在您不需要时消失。但是有 2 种非常常见的情况,您需要小心并考虑内存。

  1. 代表团。这是 Cocoa 中的常见模式,如果操作不当,可能会产生保留循环。始终将您的委托(delegate)声明为 weak 除非您有充分的理由不这样做。
  2. 关闭。闭包捕获周围范围内对象的引用并自动执行,恕不另行通知。实现闭包时,检查它是否会创建保留循环。如果是,请将问题变量声明为 weakunowned

有关更多信息,我建议您阅读官方的 Apple Swift 书籍,可以在 iBooks 或 here 中找到作为一个网站。

关于ios - swift 内存泄露怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36834935/

相关文章:

iphone - UITextView iPhone中的渐变效果?

ios - 我们可以在 ios sdk 中添加五个以上的标签栏吗?

ios - 从服务器快速加载数据iOS

objective-c - 如何在 objective-c 的启动图像上方显示 "Loading..."gif 图像?

swift - 在 collectionView 的两个不同单元格中显示 highchart 和 swiftDataTable

swift - 更新 GMSMarkers 而不阻塞主线程

swift - 是否可以将运行时从服务器恢复的图像加载到平面对象中?

ios - 在 iOS 模拟器中移动元素

ios - 什么是最有效的 : Customized or adapted ViewControllers?

objective-c - 如何保存在 UIWebview 控件中显示的 PDF(无需从网上重新加载)?