a.periz
a.periz

Reputation: 565

Objective-C Associated Objects vs NSMapTable

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

Answers (2)

malhal
malhal

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 UIImages 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

bbum
bbum

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

Related Questions