runtime(三):给分类添加一个属性

  一般的我们会用到继承父类类给一个父类添加属性,但是在某些特性的情况下(例如:团队开发中,解决相同类的冲突的时候会用到分类)需要给一个类的分类添加属性。而我们知道,分类是没有父类的,也就是说,在分类添加属性的时候,只会定义set和get方法,但是不会实际的成员变量和方法实现。例如:

@interface Dog (My)
@property(nonatomic,copy)NSString * name;
@end
@implementation Dog (My)
@end

int main(int argc, const char * argv[]) { @autoreleasepool { Dog * dog1 = [[Dog alloc]init]; dog1.name = @"dog1"; Dog * dog2 = [[Dog alloc]init];
     dog2.name = @"dog2"; NSLog(
@"dog1==%@,dog2==%@",dog1.name,dog2.name); } return 0; } //程序运行到dog1.name = @"dog1"处就会奔溃。

此时我们如果想自己给这个分类写一个set和get方法的实现。也会出现问题。例如:

@implementation Dog (My)
NSString * _name;
- (void)setName:(NSString *)name{
    _name = name;
}
- (NSString *)name{
    return _name;
}
@end
//再次运行main函数,程序结果会打印:dog1==dog2,dog2==dog2。
//这个与实际dog1.name不符,出现bug

此时,用Rumetime的方法就能实现我们的目的。核心思想就是把一个类和一个属性值产生关联。

#import "Dog+My.h"
#import <objc/runtime.h>
@implementation Dog (My)
- (void)setName:(NSString *)name{
    /*
        id object : 执行对象
        const void *key : 属性名
        id value  : 属性值
        objc_AssociationPolicy policy :copy,nonatomica等属性
     */
    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name{
    return objc_getAssociatedObject(self, @"name");
}
@end

//打印结果dog1==dog1,dog2==dog2。完成所需目的
原文地址:https://www.cnblogs.com/fusheng-it/p/5711847.html