Arrays 在Swift中从字典中获取值或键时保留循环

Arrays 在Swift中从字典中获取值或键时保留循环,arrays,dictionary,swift,retain-cycle,Arrays,Dictionary,Swift,Retain Cycle,当我从字典中获取值并将它们放入数组时,我不能再释放内存了。我试图从数组和字典中删除所有对象,但这些对象仍然存在于某个地方(没有调用deinit) 我的演奏方式如下: class MyData { let i = 0 init () { NSLog("Init") } deinit { NSLog("Deinit") } } var myDictionary:Dictionary<String, MyData>

当我从字典中获取值并将它们放入数组时,我不能再释放内存了。我试图从数组和字典中删除所有对象,但这些对象仍然存在于某个地方(没有调用deinit)

我的演奏方式如下:

class MyData {
    let i = 0
    init () {
        NSLog("Init")
    }
    deinit {
        NSLog("Deinit")
    }
}

var myDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()] 
// Init was called twice

// here is the problem: extract values from Dictionary
var myValues = Array(myDictionary.values)
myValues = []  // nothing - ok, strong references are still in the dictionary

myDictionary = [:] 
// Why Deinit was not called???
但是,如果我使用allValues而不是allKeys,那么它将不再有效

...
var anotherValues = myDictionary.allValues
anotherValues = []
myDictionary = [:]
// deinit is not called again - very scary...

我不认为这是一个循环。我可以通过迭代字典中的值来复制它,甚至不用引入数组,也不用对它们做任何操作。我在处理这个问题时注释掉了一些代码,发现它仍然不能调用Denit:

    var myDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()]
    for (_, item) in myDictionary {
        //myValues.append(item)
    }
    myDictionary = [:]
    // Why Deinit was not called???
…如果我把那条线拿出来,就可以了。这是我能找到的最简单/最奇怪的例子


因此,您的示例中的数组是一个令人费解的问题,我认为您发现了一个字典访问的bug。

有趣的实验。我想知道是每次克隆集合时都会发生这种情况,还是特定于字典键。我猜是前者。我认为这是一个缺陷。即使你把它放在自动释放池中,它也不会叫Denit。这是在操场上吗?@Matt-不,它在一个包含一个函数的项目中。我也在一个操场上进行了测试,但即使在正常情况下(最后两行代码),也不会调用Denit;游乐场倾向于将引用作为调试显示的一部分,所以我只是确保这不会混淆问题。
...
var anotherValues = myDictionary.allValues
anotherValues = []
myDictionary = [:]
// deinit is not called again - very scary...
    var myDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()]
    for (_, item) in myDictionary {
        //myValues.append(item)
    }
    myDictionary = [:]
    // Why Deinit was not called???
for _ in myDictionary { }