如何在swift中发生内存泄漏?

ios*_*ner 2 memory-management objective-c ios swift

我是ios开发的新手,我想了解内存泄漏是如何发生在swift或在内部Objective-C,任何人都能用小例子解释一下吗?

谢谢

Ale*_*loz 11

小例子:

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
}
Run Code Online (Sandbox Code Playgroud)

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

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

class A {
    weak var b: B!

    deinit {
        print("deinit of A")
    }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:添加闭包示例

考虑这个例子:

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

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

do {
    let c = C()
    c.f = {
        print(c)
    }
}
Run Code Online (Sandbox Code Playgroud)

c捕获f,f捕获c.所以我们得到了内存泄漏.

要处理闭包中的泄漏,您有两个选项 - 声明捕获的对象是weakunowned.像这样:

do {
    let c = C()
    c.f = { [weak c] in
        print(c)
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,你会使用,weak如果对象可能不存在,并成为nil关闭被调用时; 但如果您确定此时对象仍然存在,请unowned改用.

在我声明cweak封闭内部后,打印出"deinit for C" - 表示所有内容都已成功解除分配.

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

几乎所有的时间你都不必担心内存管理.这是自动完成的.对象只在您需要时存在,而在您不需要时则消失.但是,当你需要小心并考虑记忆时,有两种非常常见的情况.

  1. 代表团.它是Cocoa中的常见模式,如果做错了可能会创建保留周期.weak除非你有充分的理由不这样做,否则总是宣布你的代表.
  2. 闭包.Closure捕获周围范围内对象的引用,并自动执行,恕不另行通知.当实现闭包时,如果它将创建保留周期则chech.如果是,请将问题变量声明为weakunowned.

如需进一步信息,我建议你阅读苹果官方斯威夫特的书可以在iBooks的或发现这里作为一个网站.