【问题标题】:Objective-C Associated Objects vs NSMapTableObjective-C 关联对象 vs NSMapTable
【发布时间】:2017-02-26 16:46:16
【问题描述】:

我最近发现了NSMapTabledocnshipster),我一直想知道它是否可以用来代替关联对象。

这是一个使用标准关联对象的示例:

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)
      }
  }
}

我试图用谷歌搜索并理解其中的差异,但没有运气,因为我什至不知道如何比较这两种实现。

如何比较它们?有什么区别?

谢谢

【问题讨论】:

  • bbum 的回答给出了这两者之间区别的一个例子,但要得到一个特定于您需求的答案,您将不得不给出一些更具体的用例示例——为什么您首先需要关联对象吗?
  • 现在没什么具体的,我只是想了解技术差异以及如何比较这两种方法。

标签: objective-c foundation


【解决方案1】:

当一个对象被释放时,所有使用OBJC_ASSOCIATION_RETAIN与之关联的对象都将被释放(如果这是最后一个强引用,有时也会被释放)。

您的NSMapTable 示例不会清理dealloc


除此之外,它们在功能上相同,但实现细节不同。最重要的是线程策略; NSMapTable 不是线程安全的,而 OBJC_ASSOCIATION_RETAIN 被视为与 @property(atomic, strong) 相同。

【讨论】:

  • NSMapTable 也会释放关联的对象,如果键被弱持有而值被强持有。
【解决方案2】:

我认为情况正好相反:objc_setAssociatedObject 可以用来代替NSMapTable。不需要NSMapTable 对象来保存引用,而是将引用存储在对象本身上。尽管关联对象允许类别具有您所演示的属性,但实际上这消除了强大的功能。通过将其包装在一个类别中意味着所有UIImages 现在都具有该密钥,而通过在控制器中定义该密钥现在它可以在UIImage 中存储只有它需要的东西。

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多