1.Ivar
typedef objc_ivar * Ivar;
struct objc_ivar {
char *ivar_name;
char *ivar_type;
int ivar_offset;
#ifdef __LP64__
int space;
#endif
}
Ivar其實(shí)是一個(gè)objc_ivar的指針享怀,objc_ivar是一個(gè)struct,其中包含變量名、變量類型趟咆。
Ivar實(shí)例變量所在內(nèi)存區(qū)域初始化后不可更改添瓷,無法在運(yùn)行時(shí)增加實(shí)例變量梅屉,所以分類是無法添加實(shí)例變量的。
2.屬性
當(dāng)我們?yōu)轭愄砑訉傩詴r(shí)鳞贷,其實(shí)自動(dòng)生成了getter坯汤、setter和Ivar。其實(shí)property = Ivar + getter + setter搀愧。
但是分類中無法添加實(shí)例變量惰聂,所以直接添加屬性無法自動(dòng)生成getter和setter。必須自己實(shí)現(xiàn)這兩個(gè)方法咱筛。這種屬性被稱為關(guān)聯(lián)屬性搓幌。
static const void *tagKey = &tagKey;//自定義的關(guān)聯(lián)標(biāo)識
//setter
-(void)setTestProperty:(NSString *)testProperty{
objc_setAssociatedObject(self, tagKey, testProperty, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
//getter
-(NSString *)testProperty{
//根據(jù)tagKey, 返回關(guān)聯(lián)屬性value
return objc_getAssociatedObject(self, tagKey);
}
總結(jié)
在category中無法添加實(shí)例變量,也無法直接添加屬性迅箩。必須通過關(guān)聯(lián)屬性的方式添加溉愁。由于關(guān)聯(lián)屬性是動(dòng)態(tài)存取的,如果碰到bug極難查找饲趋,所以若非必要盡量不要在分類中增加屬性拐揭。