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

时间:2016-04-25 08:00:29

标签: ios objective-c swift memory-management

我是ios开发的新手,我想了解在swiftObjective-C中如何发生内存泄漏,是否可以用小例解释?

由于

1 个答案:

答案 0 :(得分: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
}

如果您运行此代码(可能在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。所以我们得到了内存泄漏。

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

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

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

在闭包内声明cweak之后,打印出“deinit for C” - 表示所有内容都已成功解除分配。

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

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

  1. 团。它是Cocoa中的常见模式,如果做错了可能会创建保留周期。除非您有充分的理由,否则请始终将您的代理人声明为weak
  2. 闭包。 Closure捕获周围范围内对象的引用,并自动执行,恕不另行通知。当实现闭包时,如果它将创建保留周期则chech。如果是,请将问题变量声明为weakunowned
  3. 有关详细信息,我建议您阅读官方Apple Swift书籍,该书籍可以在iBooks中找到,或者here可以在网站上找到。