Category一般称为分类,扩展,主要是为一些无法知道源码的类比如系统类,添加一些功能方法
可以添加的有,实例方法,类方法
category不可以添加属性的原因
分类本身不是一个类,其本质是在运行时,将定义的方法添加到原类的方法列表中的
成员变量这个概念是相对于类存在的,既然分类不是一个类,那它就不能添加成员变量(实例变量),从而也不能添加属性
因为添加一个属性,其实是做了三件事
@property (nonatomic, assign) int age;
1、生成了同名的,以_开头的成员变量: _age
2、定义了getter和setter,并且在.m文件中实现了这两个方法
3、在实现代码部分(.m 文件),实现了这两个方法
- (int)age;
- (void)setAge:(int)age;
在分类中添加一个属性,其实只是定义了getter和setter方法,没有实现这两个方法,也没能生成同名的以_开头的成员变量
image.png image.png访问该属性时崩溃
-[Person age]: unrecognized selector sent to instance 0x7fd50af0f410
可以在.m文件中定义这两个方法,在外部访问age时不会再崩溃
- (int)age {
return _age;
}
- (void)setAge:(int)age {
_age = age;
}
但是在里面访问_age会报错
image.png那如何实现呢,这就涉及到了使用runtime提供的两个关联对象的方法了
objc_getAssociatedObject(...)
objc_setAssociatedObject(...)
static const char * ageKey = "AgeKey";
static const char * nameKey = "NameKey";
- (int)age {
return [objc_getAssociatedObject(self, ageKey) intValue];
}
- (void)setAge:(int)age {
objc_setAssociatedObject(self, ageKey, @(age), OBJC_ASSOCIATION_ASSIGN);
}
- (NSString *)name {
return objc_getAssociatedObject(self, nameKey);
}
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, nameKey, name, OBJC_ASSOCIATION_COPY);
}
这样可以达到正常使用这个属性的目的,但是仍然没有生成_age这个成员变量
Person *p = [Person new];
p.age = 20;
p.name = @"张三";
NSLog(@"age = %d, name = %@",p.age, p.name);
//console 打印:age = 20, name = 张三
网友评论