Objective-Cruntime提供了AssociativeReferences支持,也就是说每一个对象都有一个可选的dictionary字典,我们可以向其添加key/value对。
这是一个非常强大的功能,我们都知道Objective-C中支持category,我们可以在category中添加方法,但是它不允许我们添加实例变量。
通过这个AssociativeReferences我们就可以在category中添加实例变量了,但是需要指出的是这个是假的实例变量,变量实际上并不是类对象的一部分,而是存储在对象的AssociativeReferences的dictionary中;也就是说我们这样添加的变量并不改变类对象的大小。
在Objective-Cruntime中提供了访问这个dictionary的方法
[代码]c#/cpp/oc代码:
1 | void objc_setAssociatedObject(id object , const void *key, idvalue,objc_AssociationPolicypolicy) |
2 | id
objc_getAssociatedObject(id object , const void *key) |
然后我们就来看看如何来使用AssociativeReferences为category添加property:
[代码]c#/cpp/oc代码:
03 | @ interface UIView
(DHStyleManager) |
04 | @property (nonatomic,copy)NSString*styleName; |
07 | @implementation UIView(DHStyleManager) |
09 | -
( void )setStyleName:(NSString
*)styleName |
11 | objc_setAssociatedObject(self, &kDHStyleKey,styleName,OBJC_ASSOCIATION_COPY); |
16 | return objc_getAssociatedObject(self,
&kDHStyleKey); |
也就是说我们需要利用@dynamic自己为property提供getter和setter,在getter和setter中访问AssociativeReferences
为了方便期间,可以封装一个宏来访问AssociatvieReferences,代码如下:
[代码]c#/cpp/oc代码:
01 | @ interface UIView
(DHStyleManager) |
02 | @property (nonatomic,copy)NSString*styleName; |
05 | @implementation UIView(DHStyleManager) |
06 | ADD_DYNAMIC_PROPERTY(NSString*,styleName,setStyleName); |
11 | #define ADD_DYNAMIC_PROPERTY(PROPERTY_TYPE,PROPERTY_NAME,SETTER_NAME)\ |
12 | @dynamic PROPERTY_NAME;\ |
13 | static char kProperty##PROPERTY_NAME;
\ |
14 | -
(PROPERTY_TYPE)PROPERTY_NAME\ |
16 | return ( PROPERTY_TYPE)objc_getAssociatedObject(self,&(kProperty##PROPERTY_NAME));\ |
19 | -
( void ) SETTER_NAME:(PROPERTY_TYPE)PROPERTY_NAME\ |
21 | objc_setAssociatedObject(self, &kProperty##PROPERTY_NAME,PROPERTY_NAME,OBJC_ASSOCIATION_RETAIN);\ |