头文件:html
#import <objc/runtime.h>
Objective-C 开发者习惯于警戒运行时的东西,理由是运行时改变了运行在它上面代码的实际结构。ios
另外一方面,<objc/runtime.h>
的功能就是为应用或框架增长更强大的新特性,是其余的方式没法git
实现的。同时它也可能破坏原来代码的逻辑结构,一切与之可能进行的交互,都将有可怕的反作用。github
给咱们带来极大的惶恐,所以,咱们称之为浮士德,也是NSHipster读者常常被所要求的科目之一:缓存
关联的对象。关联的对象或关联的引用,他们本来是Objective-C的2.0运行时的新特性,在OS Xapp
雪豹中介绍(可在iOS 4的)的功能。它在运行时键值允许对象为任意值,这个条目是在框架
<objc/ runtime.h>声明的,有如下三个C函数:异步
objc_setAssociatedObject
objc_getAssociatedObject
objc_removeAssociatedObjects
为何会这样有用吗?它容许开发人员在分类中自定义属性,拓展的类,弥补Objective-C的这个缺陷。ide
NSObject+AssociatedObject.h
@interface NSObject (AssociatedObject) @property (nonatomic, strong) id associatedObject; @end
NSObject+AssociatedObject.m @implementation NSObject (AssociatedObject) @dynamic associatedObject; - (void)setAssociatedObject:(id)object { objc_setAssociatedObject(self, @selector(associatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (id)associatedObject { return objc_getAssociatedObject(self, @selector(associatedObject)); }
人们一般的建议是使用静态字符,或者更好的是指针。这基本上保证一个任意的值是固定的、惟一的,函数
并且仅限于getter和setter方法中使用:
static char kAssociatedObjectKey; objc_getAssociatedObject(self, &kAssociatedObjectKey);
然而,一个更简单的解决方案存在:只使用一个SEL。
值能够根据由枚举类型objc_AssociationPolicy定义的行为相关联的物体上
Behavior | @property Equivalent | Description |
---|---|---|
OBJC_ASSOCIATION_ASSIGN | @property (assign) or @property (unsafe_unretained) | Specifies a weak reference to the associated object. |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | @property (nonatomic, strong) | Specifies a strong reference to the associated object, and that the association is not made atomically. |
OBJC_ASSOCIATION_COPY_NONATOMIC | @property (nonatomic, copy) | Specifies that the associated object is copied, and that the association is not made atomically. |
OBJC_ASSOCIATION_RETAIN | @property (atomic, strong) | Specifies a strong reference to the associated object, and that the association is made atomically. |
OBJC_ASSOCIATION_COPY | @property (atomic, copy) | Specifies that the associated object is copied, and that the association is made atomically. |
有人可能控制不住地各类诱惑,在他们某些关联的对象时调用objc_removeAssociatedObjects()。
可是,如文档中描述的,你基本没有将有机会亲自调用它: 此函数的主要目的是能够很容易将对象返回
到“原始状态”,你不该该使用这个函数从对象通常移除关联,由于它也消除了其余对象可能已添加到该
对象关联。一般状况下,你应该使用objc_setAssociatedObject 设置nil,以清除关联。
相关联的对象应被看做是不得已的方法,而不是寻找问题的解决方案(说真的,类自己真的不该该在工具链的顶端开始)。 如同任何聪明的把戏,骇客攻击,或解决方法,通常都会积极寻求应用的场合,尤为是了解以后,这是人的一种天然的倾向 。尽你所能地理解和欣赏时,这是正确的解决方案,保存本身被轻蔑地问:“为何要以神的名义”,而后你决定去解决。
相关代码: