Objective-C runtime提供了Associative References支持,也就是说每一个对象都有一个可选的dictionary字典,我们可以向其添加key/value对。
这是一个非常强大的功能,我们都知道Objective-C中支持category,我们可以在category中添加方法,但是它不允许我们添加实例变量。
通过这个Associative References我们就可以在category中添加实例变量了,但是需要指出的是这个是假的实例变量,变量实际上并不是类对象的一部分,而是存储在对象的Associative References的dictionary中;也就是说我们这样添加的变量并不改变类对象的大小。
在Objective-C runtime中提供了访问这个dictionary的方法
[代码]c#/cpp/oc代码:
1 |
void objc_setAssociatedObject(id object , const void *key,
id value, objc_AssociationPolicy policy) |
2 |
id
objc_getAssociatedObject(id object , const void *key) |
然后我们就来看看如何来使用Associative References为category添加property:
[代码]c#/cpp/oc代码:
01 |
static char kDHStyleKey; |
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); |
14 |
-
(NSString*)styleName |
16 |
return objc_getAssociatedObject(self,
&kDHStyleKey); |
也就是说我们需要利用@dynamic自己为property提供getter和setter,在getter和setter中访问Associative References
为了方便期间,可以封装一个宏来访问Associatvie References,代码如下:
[代码]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); \ |
参考:
http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/
http://inchoo.net/mobile-development/iphone-development/how-to-add-a-property-via-class-category/
http://www.davidhamrick.com/2012/05/28/Adding-Properties-to-an-Objective-C-Category-Revisted.html