在分類(lèi)中添加的屬性,不會(huì)自動(dòng)生成實(shí)例變量,分類(lèi)添加的屬性其實(shí)是添加該屬性的getter與setter方法。用@property聲明的屬性只會(huì)生成setter和getter的聲明,而不會(huì)生成成員變量和實(shí)現(xiàn)setter、getter方法。
-1 當(dāng)聲明了一個(gè)屬性,編譯器會(huì)報(bào)錯(cuò)
//Person.h文件
#import "Person.h"
@interface Person (test)
@property (nonatomic,copy) NSString *name;
@end
//Person.m文件
#import "Person+test.h"
@implementation Person (test)
@end
報(bào)錯(cuò)如下:

意思是:屬性 name的setter和getter方法需要自己實(shí)現(xiàn),或者使用 @dynamic。
PS:也就是說(shuō)分類(lèi)中只可以添加方法,但是不能添加成員變量
在runtime函數(shù)中,有一個(gè)class_addIvar()函數(shù)用于給類(lèi)添加成員變量,這個(gè)函數(shù)只能在“構(gòu)建一個(gè)類(lèi)的過(guò)程中”調(diào)用。一旦完成類(lèi)定義,就不能再添加成員變量了,文檔中有說(shuō)明:This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.
意思是:這個(gè)class_addIvar()函數(shù)只能在objc_allocateClassPair函數(shù)調(diào)用之后,在objc_registerClassPair調(diào)用之前進(jìn)行調(diào)用。
成員變量屬于類(lèi)實(shí)例,類(lèi)實(shí)例是一段內(nèi)存空間,當(dāng)一個(gè)類(lèi)在實(shí)例化之后,這個(gè)內(nèi)存空間的布局已經(jīng)完成了,布局無(wú)法進(jìn)行更改,因而成員變量也無(wú)法更改。但是屬性和方法不屬于類(lèi)實(shí)例
通過(guò)runtime來(lái)給category添加分類(lèi)
//Person.h文件
#import "Person.h"
@interface Person (test)
/** 姓名*/
@property (nonatomic,copy) NSString *name;
@end
#import "Person+test.h"
#import <objc/runtime.h>
static const void* nameKey = &nameKey;
@implementation Person (test)
-(void)setName:(NSString *)name
{
objc_setAssociatedObject(self, nameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)name
{
return objc_getAssociatedObject(self, nameKey);
}
@end