我试图弄清楚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中仍然有一个元素?

最佳答案

当您不在乎释放键/值的时间时,NSMapTableweak行为选项最有效,但是,您确实关心的是键/值不会被强烈保留,而是会在感兴趣的对象变成某个位置后被释放nil

为什么这样?

作为基础类,NSMapTable的作者必须兼顾功能和性能。

因此,作为性能的“优化”,他们选择不立即将变为nil的弱引用对象从映射表中删除...!相反,这种情况在可以有效完成的情况下“较晚”发生(例如,当映射表在内部被调整大小时)。

正如@Luke在他的回答中提到的那样,请参见以下有关NSMapTable行为的实验的出色文章,以了解更多详细信息:

http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/

07-27 20:52