Objective-C 关联对象与 NSMapTable
Objective-C Associated Objects vs NSMapTable
最近发现了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)
}
}
}
我尝试 google 并理解其中的差异,但没有成功,因为我什至不知道如何比较这两个实现。
我如何比较它们?有什么区别?
谢谢
当一个对象被释放时,所有使用 OBJC_ASSOCIATION_RETAIN
与之关联的对象都将被释放(如果那是最后一个强引用,有时会被释放)。
您的 NSMapTable
示例不会在 dealloc
上清除。
除此之外,它们在功能上是相同的,但具有不同的实现细节。最重要的是线程策略; NSMapTable
不是线程安全的,而 OBJC_ASSOCIATION_RETAIN
被视为与 @property(atomic, strong)
相同。
我认为是相反的:objc_setAssociatedObject
可以用来代替 NSMapTable
。不需要 NSMapTable
对象来保存引用,而是将引用存储在对象本身上。尽管关联对象允许类别具有您所演示的属性,但实际上这会删除强大的功能。通过将其包装在一个类别中意味着所有 UIImage
现在都拥有该密钥,而通过在控制器中定义密钥现在它可以将仅需要的内容存储在 UIImage
中。
最近发现了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)
}
}
}
我尝试 google 并理解其中的差异,但没有成功,因为我什至不知道如何比较这两个实现。
我如何比较它们?有什么区别?
谢谢
当一个对象被释放时,所有使用 OBJC_ASSOCIATION_RETAIN
与之关联的对象都将被释放(如果那是最后一个强引用,有时会被释放)。
您的 NSMapTable
示例不会在 dealloc
上清除。
除此之外,它们在功能上是相同的,但具有不同的实现细节。最重要的是线程策略; NSMapTable
不是线程安全的,而 OBJC_ASSOCIATION_RETAIN
被视为与 @property(atomic, strong)
相同。
我认为是相反的:objc_setAssociatedObject
可以用来代替 NSMapTable
。不需要 NSMapTable
对象来保存引用,而是将引用存储在对象本身上。尽管关联对象允许类别具有您所演示的属性,但实际上这会删除强大的功能。通过将其包装在一个类别中意味着所有 UIImage
现在都拥有该密钥,而通过在控制器中定义密钥现在它可以将仅需要的内容存储在 UIImage
中。