When I grab values from a Dictionary and put them into Array, I can't release memory any more. I tried to remove all object from Array and Dictionary, but these object still exist somewhere (deinit were not called).
I was playing in the following way:
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???
If I remove these two lines for value extraction, then Deinit is called normally
var anotherDictionary:Dictionary<String, MyData> = ["key1":MyData(), "key2":MyData()]
anotherDictionary = [:]
// Deinit is called twice
var myArray:MyData[] = [MyData(), MyData()]
myArray = []
// Deinit is called twice
What am I doing wrong here?
How the objects should be removed in the proper way to release memory when they don't needed anymore? The problem happens only when keys or values are extracted from Dictionary (Dictionary.values or Dictionary.keys).
EDIT:
I made a workaround for this case. If I use NSDictionary instead of Dictionary and extract keys first and then take values in a for-loop, then it works.
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...
But, if I use allValues instead of allKeys, then it won't work any more.
...
var anotherValues = myDictionary.allValues
anotherValues = []
myDictionary = [:]
// deinit is not called again - very scary...