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 中。