gpt4 book ai didi

ios - swift 内存泄露怎么办?

转载 作者:可可西里 更新时间:2023-10-31 23:56:24 24 4
gpt4 key购买 nike

我是 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com