我正在试图弄清楚NSMapTable是如何工作的 所以我在游乐场尝试以下代码:
class Person {
var name: String
init(name: String ) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
var hobyePerson : NSMapTable? = NSMapTable<Person, NSMutableString>
(keyOptions: .weakMemory, valueOptions: .weakMemory)
var rob : Person? = Person(name: "Rob Appleseed") // print : Rob Appleseed is being initialized
hobyePerson?.setObject("golf", forKey: rob)
hobyePerson?.count // return : 1
rob = nil // print : Rob Appleseed is being deinitialized
hobyePerson?.count // return : 1 (WHY ???!!!!)
写在documentation中:“键和/或值可选地”弱“,以便在回收其中一个对象时删除条目。”
为什么即使我初始化了对象,以便在取消分配rob时它对键值对的引用很弱,我仍然在hobyePerson中有一个元素?
答案 0 :(得分:1)
是的,这是一种奇怪而不幸的行为。 This article在某种程度上进入了它。虽然它没有特别探讨弱到弱,但描述的行为是相同的。正如该作者所指出的那样,hobyePerson.keyEnumerator().allObjects.count
和hobyePerson.objectEnumerator().allObjects.count
将在所有这些结尾处按预期包含0。他还指出,Apple在Mountain Lion release notes中记录了这种行为。
但是,目前不建议使用弱到强的NSMapTables 弱键的强值值为零,不会得到 清除(并释放)直到/除非地图表自行调整大小。
抱歉,我没有更好的解释。
答案 1 :(得分:1)
NSMapTable
weak
行为选项在发布键/值时不关心时效果最佳,相反,您确实关心键/值在感兴趣的对象变为nil
之后的某个时刻,将被强烈保留并将被释放。
为什么会这样?
作为基础课程,NSMapTable
的作者必须平衡功能和性能。
因此,作为性能的“优化”,他们选择成为nil
的弱引用对象不会立即从地图表中删除......!相反,当它可以有效地完成时会发生这种情况 - 例如当地图表在内部调整大小时等等。
正如@Luke在他的回答中提到的,请参阅这篇关于NSMapTable
行为的实验的优秀文章,以获取更多细节:
http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/