当我从字典中获取值并将它们放入数组时,我无法再释放内存。我试图从 Array 和 Dictionary 中删除所有对象,但这些对象仍然存在于某处(没有调用 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???
如果我去掉这两行取值,那么Deinit就正常调用了
var anotherDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()]
anotherDictionary = [:]
// Deinit is called twice
var myArray:MyData[] = [MyData(), MyData()]
myArray = []
// Deinit is called twice
我在这里做错了什么?
当对象不再需要时,如何以正确的方式删除对象以释放内存?仅当从字典(Dictionary.values 或 Dictionary.keys)中提取键或值时才会出现此问题。
编辑:
我为这种情况做了一个解决方法。如果我使用 NSDictionary 而不是 Dictionary 并首先提取键,然后在 for 循环中获取值,那么它就可以工作。
var myDictionary:NSDictionary = ["key1":MyData(), "key2":MyData()]
// called Init twice
var myKeys:String[] = myDictionary.allKeys as String[]
var myValues:MyData[] = []
for key in myKeys {
myValues.append(myDictionary[key] as MyData)
}
myKeys = []
myDictionary = [:]
myValues = []
// Deinit is now called twice, but I'm not sure about keys...
但是,如果我使用 allValues 而不是 allKeys,那么它将不再起作用。
...
var anotherValues = myDictionary.allValues
anotherValues = []
myDictionary = [:]
// deinit is not called again - very scary...
最佳答案
我不认为这是一个保留周期。我可以简单地通过迭代字典中的值来重现这一点,甚至无需引入数组,无需对它们执行任何操作。当我注释掉一些代码并发现这仍然没有调用 deinit 时,我正在玩这个问题:
var myDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()]
for (_, item) in myDictionary {
//myValues.append(item)
}
myDictionary = [:]
// Why Deinit was not called???
如果您完全删除 for
循环,deinit 将按预期调用。如果你把它放回去——只是循环,什么都不做——那么你不会得到 deinit。
我会说这是某种字典访问中的错误;它不像 Array 和 Dictionary 之间的引用循环那么复杂。
我可以用它作为我的 for
循环重现上面的内容:
for _ in myDictionary { }
...如果我去掉那条线,它就没问题了。这是我能找到的最简单/最奇怪的情况。
因此,您的示例中的数组是一条红鲱鱼,我认为您发现了字典访问的错误。
关于arrays - 在 Swift 中从字典中获取值或键时保留循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24700178/