Swift 3 & iOS 10 错误的内存泄漏错误

Swift 3 & iOS 10 false memory leak bug

与 iOS 10 & Swift 3 一起使用时,Xcode 8 中似乎存在(错误的)内存泄漏错误。

以下代码报告 Instruments 和 Xcode 8 内存调试器中的内存泄漏:

class SomeClass: NSObject {
    var view: SomeView!

    deinit {
        print("SomeClass deinit")
    }
}

class SomeView: UIView {
    weak var reference: SomeClass?

    deinit {
        print("SomeView deinit")
    }
}

class ViewController: UIViewController {
    var someProperty: SomeClass?

    override func viewDidLoad() {
        super.viewDidLoad()

        let c = SomeClass()
        let v = SomeView()
        c.view = v
        v.reference = c

        someProperty = c
    }
}

我尝试了不同的变体来确认它确实是一个错误,我的发现是:

  1. 当您不将示例代码中的 c 分配给 someProperty 时,两个实例都将在各自的 deinit 中打印字符串。真正的强引用循环不会 deinit。
  2. SomeClass 不继承自 NSObject 时,不会发生此错误。
  3. 使用 Swift 2.2 时,不会发生这种情况。
  4. 使用 iOS 9- 时,不会发生这种情况。
  5. 一旦在代码中某处将 someProperty 设置为 nil,两个实例都会被 deinited。 Xcode 8 内存调试器确认没有内存泄漏。然而,在 Instruments 中,这种变化并没有反映出来——这是正确的,因为真正的内存泄漏可能不会得到解决。

仅供参考,仅当它分配给 UIViewController 的 属性 时才会发生这种情况。我最初是在单例对象中发现这种行为的。

iOS 10.3(第一个测试版)和 Xcode 8.3(第一个测试版)似乎已修复。