Reputation: 565
I recently discovered NSMapTable
(doc, nshipster) and I have been wondering whether it can be used in place of associated objects.
Here's an example using standard associated objects:
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
}
}
}
versus an implementation using 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)
}
}
}
I tried to google and understand the differences with no luck, as I don't even know how I can compare the two implementations.
How can I compare them? What are the differences?
Thanks
Upvotes: 1
Views: 567
Reputation: 30582
I believe it is the other way around: objc_setAssociatedObject
can be used in place of NSMapTable
. Instead of requiring a NSMapTable
object to hold the references, the reference is stored on the object itself. And although associated objects allow categories to have properties as you demonstrated, in fact that removes powerful functionality. By wrapping it in a category means all UIImage
s now have that key, whereas by defining the key in the controller now it can store things in UIImage
that only it requires.
Upvotes: 0
Reputation: 162712
When an object is deallocated, all objects that are associated with it using OBJC_ASSOCIATION_RETAIN
will be released (and sometimes deallocated if that was the last strong reference).
Your NSMapTable
example won't clean up on dealloc
.
Beyond that, they are functionally the same, but have different implementation details. The most significant is the threading policy; NSMapTable
is not thread safe whereas OBJC_ASSOCIATION_RETAIN
is treated the same as an @property(atomic, strong)
.
Upvotes: 2