在分类中添加的属性,不会自动生成实例变量,分类添加的属性其实是添加该属性的getter与setter方法。用@property声明的属性只会生成setter和getter的声明,而不会生成成员变量和实现setter、getter方法。
-1 当声明了一个属性,编译器会报错
//Person.h文件
#import "Person.h"
@interface Person (test)
@property (nonatomic,copy) NSString *name;
@end
//Person.m文件
#import "Person+test.h"
@implementation Person (test)
@end
报错如下:
意思是:属性 name的setter和getter方法需要自己实现,或者使用 @dynamic。
PS:也就是说分类中只可以添加方法,但是不能添加成员变量
在runtime函数中,有一个class_addIvar()函数用于给类添加成员变量,这个函数只能在“构建一个类的过程中”调用。一旦完成类定义,就不能再添加成员变量了,文档中有说明:This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.
意思是:这个class_addIvar()函数只能在objc_allocateClassPair函数调用之后,在objc_registerClassPair调用之前进行调用。
成员变量属于类实例,类实例是一段内存空间,当一个类在实例化之后,这个内存空间的布局已经完成了,布局无法进行更改,因而成员变量也无法更改。但是属性和方法不属于类实例
通过runtime来给category添加分类
//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