当从NSObject派生时,Swift iOS内存泄漏指示XCode8

时间:2016-10-14 13:44:11

标签: ios swift memory-leaks nsobject

Xcode8显示仪器和内存图中的内存泄漏。我把它缩小到这个:从NSObject派生出一个泄漏指示。我不知道为什么。

我需要一个NSObject才能使用@objc指令。

存储在mDict字典中的Test实例表示为Xcode中的泄漏。

这是在运行iOS10.0的iPhone5s模拟器中作为iOS Single-View-Application项目运行

import Foundation

class Test: NSObject  // <-- derived from NSObject produces leak indication below
{
    static var cTest: Test! = nil
    var mDict: [String : Test] = Dictionary<String, Test>()

    static func test() -> Void {
        cTest = Test()
        cTest.mDict["test"] = Test() // <-- alleged leak
    }
}

class Test  // <-- NOT derived from NSObject, NO leak indication
{
    static var cTest: Test! = nil
    var mDict: [String : Test] = Dictionary<String, Test>()

    static func test() -> Void {
        cTest = Test()
        cTest.mDict["test"] = Test() // <-- NO leak
    }
}

// from AppDelegate didFinishLaunchingWithOptions
// ...
    Test.test()
// ...

3 个答案:

答案 0 :(得分:0)

swift中的内存gestion与类的目标c略有不同。比做class Test: NSObject你可能会错过这个特征。 如果您尝试class Test: AnyObject,则必须解决问题。

或者在您完成任务时尝试使用deinit

class Test: NSObject  // <-- using deinit
{
   static var cTest: Test! = nil
   var mDict: [String : Test] = Dictionary<String, Test>()

   static func test() -> Void {
      cTest = Test()
      cTest.mDict["test"] = Test() // <-- alleged leak
   }

   deinit {

   }
}

但最佳做法是将其声明为weak变量,例如weak var test: Test?

答案 1 :(得分:0)

这似乎在Xcode版本8.2(8C38)中得到修复。不再显示泄漏。

答案 2 :(得分:0)

这与原始问题基本相同。这是我的测试代码有类似的问题。因人而异。在iPad上运行iOS iOS版本8.2(8C38)

import UIKit

class Thing {}

class Test: NSObject
{
    static let shared = Test()
    var dictionary: [String: Thing] = [:]

    func method() {
        dictionary = ["value": Thing()]
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        Test.shared.method()
        print("Leaky leaky... click on the memory visualizer to see issues.")
    }
}

如果删除NSObject,问题就会消失。我为它的价值提出了一个雷达。

如果我作为命令行工具运行并使用命令行leaks命令进行检查,我就不会看到问题。