10、在既有类中使用关联对象存放自定义数据

可以给某对象关联许多其他对象,这些对象通过“键”来区分。存储对象值的时候,可以指明“存储策略”(storage policy),用以维护相应的“内存管理语义”。策略有名为objc_AssociationPolicy的枚举所定义:

objc_AssociationPolicy关联类型

等效的@property属性

OBJC_ASSOCIATION_ASSIGN

assign

OBJC_ASSOCIATION_RETAIN_NONATOMIC

nonatomic,retain

OBJC_ASSOCIATION_COPY_NONATOMIC

nonatomic,copy

OBJC_ASSOCIATION_RETAIN

retain

OBJC_ASSOCIATION_COPY

copy

​ 以下方法可以管理关联对象:

  • void objc_setAssociatedObject(id object, void* key, id value, objc_AssociationPolicy policy)此方法以给定的键和策略为某对象设置关联对象值

  • id objc_getAssociatedObject(id object, void* key)此方法根据给定的键从某对象中获取相应的关联对象值

  • void objc_removeAssociatedObject(id object)此方法移除指定对象的全部关联对象

    ​ 可以把某对象想像成NSDictionary,把关联到该对象的值理解为字典中的条目,存储关联对象的值就相当于在字典对象调用setObject:valueforKey:objectForKey:方法。然而两者之间有个重要差别:设置关联对象时用的键(key)时一个“不透明的指针”(opaque pointer)。如果在两个键上调用isEqual:方法返回YES,那么字典人为二者相等;而在设置关联对象值时,若向令两个键匹配到同一个字,则二则必须是完全相同的指针才行。鉴于此,在设置关联对象值时,通常使用静态全局变量做键。

关联对象用法举例:

​ 可以看这篇文章(iOS_理解“属性”(property)这一概念)的 @dynamic(二-2):在Category中为类添加属性。

要点:

  • 可以通过“关联对象”机制来把两个对象连起来

  • 定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”与“非拥有关系”

  • 只有在其他做法不可行时才应选用关联对象,因为这种做法通常会引入难于查找的bug

Last updated

Was this helpful?