【问题标题】:How memory leak will occur in swift?swift中会如何发生内存泄漏?
【发布时间】:2016-04-25 08:00:28
【问题描述】:

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

谢谢

【问题讨论】:

  • 保留周期,使用低 API(如 CGPath 等,您应该称自己为 CGReleaseStuff)等。
  • retain cycles - 多个对象相互持有强引用:A 引用 BB 引用 A

标签: ios objective-c swift memory-management


【解决方案1】:

小例子:

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”——这意味着所有内容都已成功解除分配。

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

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

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

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

【讨论】:

  • 感谢您的示例。需要这方面的一些信息。在这种情况下,只有内存会泄漏吗?或任何其他条件列表都可能发生内存泄漏
  • 关闭也可能导致内存泄漏。我将编辑我的答案以提供更多信息。
  • 为什么在第一个示例中需要 do 块?
猜你喜欢
  • 2018-06-08
  • 2011-06-28
  • 1970-01-01
  • 2020-03-19
  • 2011-05-13
  • 1970-01-01
  • 2014-07-10
  • 1970-01-01
  • 2021-11-18
相关资源
最近更新 更多