分類是不能合成屬性的,因?yàn)楹铣蓪傩詴?huì)生成對應(yīng)的實(shí)例變量,而分類是不允許添加實(shí)例變量的玛荞。
雖然不能添加實(shí)例變量,但是可以添加屬性可以的呕寝。只不過需要自己在分類中實(shí)現(xiàn)set和get方法勋眯,同時(shí)標(biāo)記屬性為動(dòng)態(tài)獲取。
其中一種方法叫做關(guān)聯(lián)引用下梢,實(shí)現(xiàn)了用存取器來訪問屬性客蹋。當(dāng)然實(shí)際上沒有實(shí)例變量,所以本質(zhì)上只不過增加了get和set 方法而已孽江。
#import "Person+EmailAddress.h"
@implementation Person (EmailAddress)
static char emailKey;
- (NSString *)emailAddress {
return objc_getAssociatedObject(self, &emailKey);
}
- (void)setEmailAddress:(NSString *)emailAddress {
objc_setAssociatedObject(self, &emailKey, emailAddress, OBJC_ASSOCIATION_COPY);
}
@end
注意讶坯,關(guān)聯(lián)引用是基于鍵的內(nèi)存地址的,而不是值的岗屏。emailKey 中存著什么不重要闽巩,重要的是內(nèi)存地址是不變的。這也是一般用未賦值的static char 變量作為鍵的原因担汤。
總結(jié):
- 我們知道category是不能創(chuàng)建實(shí)例變量的涎跨,但我們可以通過關(guān)聯(lián)引用來達(dá)到這樣的目的。特別是當(dāng)你不持有這個(gè)類崭歧,比如說系統(tǒng)的類隅很,而你又的確需要添加一個(gè)property。
- 用來標(biāo)記是哪一個(gè)屬性的key常見有三種寫法,但代碼效果是一樣的叔营,如下:
//利用靜態(tài)變量地址唯一不變的特性
1屋彪、static void *strKey = &strKey;
2、static NSString *strKey = @"strKey";
3绒尊、static char strKey;
- 關(guān)聯(lián)策略是個(gè)枚舉值畜挥,解釋如下:
enum {
OBJC_ASSOCIATION_ASSIGN = 0, //關(guān)聯(lián)對象的屬性是弱引用 OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //關(guān)聯(lián)對象的屬性是強(qiáng)引用并且關(guān)聯(lián)對象不使用原子性
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象不使用原子性
OBJC_ASSOCIATION_RETAIN = 01401, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性
OBJC_ASSOCIATION_COPY = 01403 //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性
};