ema*_*cos 5 weak-references ios strong-references swift
我想弄清楚 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 ???!!!!)
Run Code Online (Sandbox Code Playgroud)
如文档中所写:“键和/或值可以选择“弱”保存,以便在回收对象之一时删除条目。
为什么即使我初始化了对象,以便在释放 rob 时它对键值对具有弱引用,但我仍然在 hobyePerson 中有一个元素?
NSMapTableweak当您不关心键/值何时被释放时,的行为选项最有效,相反,您确实关心键/值不会被强烈保留,并且会在感兴趣的对象变为 之后的某个时间点被释放nil。
为什么这样?
作为基础类,作者NSMapTable必须平衡功能和性能。
因此,作为性能的“优化”,他们选择了nil不会立即从映射表中删除的弱引用对象......!相反,这会在可以有效完成时“稍后”发生 - 例如当映射表内部调整大小时等。
正如@Luke 在他的回答中也提到的,有关NSMapTable更多详细信息,请参阅这篇关于对的行为进行的实验的优秀文章:
http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/
是的,这是一种奇怪且不幸的行为。这篇文章对此进行了一些深入的探讨。尽管它没有具体探讨弱对弱,但所描述的行为是相同的。正如该作者所指出的,hobyePerson.keyEnumerator().allObjects.count和hobyePerson.objectEnumerator().allObjects.count将在所有这一切结束时按预期包含 0 。他还指出,苹果公司已经在Mountain Lion 发行说明中记录了这种行为。
\n\n\n但是,目前不建议使用从弱到强的 NSMapTable,因为弱键的强值在映射表调整大小之前不会被清除(并释放),从而获得 0\xe2\x80\x99d 的值。本身。
\n
抱歉我没有更好的解释给你。
\n