Mat*_*jaz 9 arrays dictionary retain-cycle swift
当我从Dictionary中获取值并将它们放入Array时,我无法释放内存.我试图从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???
Run Code Online (Sandbox Code Playgroud)
如果我删除这两行以进行值提取,则会正常调用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
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
应该如何以适当的方式删除对象,以便在不再需要时释放内存?只有从Dictionary(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...
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用allValues而不是allKeys,那么它将不再起作用.
...
var anotherValues = myDictionary.allValues
anotherValues = []
myDictionary = [:]
// deinit is not called again - very scary...
Run Code Online (Sandbox Code Playgroud)
我不认为这是一个保留周期.我可以简单地通过迭代字典中的值来重现这一点,甚至不引入数组,也不需要对它们做任何事情.当我评论出一些代码并发现它仍然没有调用deinit时,我正在玩这个问题:
var myDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()]
for (_, item) in myDictionary {
//myValues.append(item)
}
myDictionary = [:]
// Why Deinit was not called???
Run Code Online (Sandbox Code Playgroud)
如果for完全取出循环,则按预期调用deinit.如果你把它放回 - 只是循环,没有做任何事情 - 那么你就不会得到一个deinit.
我会说这是某种字典访问中的错误; 它没有Array和Dictionary之间的参考周期那么复杂.
我可以将此作为我的for循环重现以上内容:
for _ in myDictionary { }
Run Code Online (Sandbox Code Playgroud)
......如果我把这条线拿出来,那就很好了.这是我能找到的最简单/最奇怪的案例.
所以,你的例子中的数组是一个红色的鲱鱼,我认为你发现了一个字典访问错误.
| 归档时间: |
|
| 查看次数: |
1075 次 |
| 最近记录: |