我最近发现了NSMapTable
(doc,nshipster),我一直想知道它是否可以代替相关对象。
以下是使用标准关联对象的示例:
var fooKey = "foo"
extension UIView {
var foo: UIImage? {
set {
objc_setAssociatedObject(self, &fooKey, newValue, .OBJC_ASSOCIATION_RETAIN)
}
get {
return objc_getAssociatedObject(self, &fooKey) as? UIImage
}
}
}
与使用NSMapTable
的实现相比:
let barTable = NSMapTable<UIView, UIImage>(keyOptions: [.weakMemory], valueOptions: [.strongMemory])
extension UIView {
var bar: UIImage? {
get {
return barTable.object(forKey: self)
}
set {
barTable.setObject(newValue, forKey: self)
}
}
}
我试图谷歌并且没有运气就能理解差异,因为我甚至不知道如何比较这两种实现方式。
我如何比较它们?有什么区别?
由于
答案 0 :(得分:2)
当一个对象被释放时,所有使用OBJC_ASSOCIATION_RETAIN
与之关联的对象都将被释放(如果这是最后一个强引用,有时会被解除分配)。
您的NSMapTable
示例无法清除dealloc
。
除此之外,它们在功能上是相同的,但具有不同的实现细节。最重要的是线程策略; NSMapTable
不是线程安全的,而OBJC_ASSOCIATION_RETAIN
与@property(atomic, strong)
的处理方式相同。
答案 1 :(得分:0)
我相信这是另一回事:objc_setAssociatedObject
可以代替NSMapTable
。不需要将NSMapTable
对象保存引用,而是将引用存储在对象本身上。而且,尽管关联的对象允许类别具有您所演示的属性,但实际上,它删除了强大的功能。通过将其包装在类别中,意味着所有UIImage
现在都具有该密钥,而现在通过在控制器中定义该密钥,它可以将仅需要的内容存储在UIImage
中。