关于Category关联属性

关联属性的相关方法及优缺点

方法1 在分类中定义全局参数接收。

@implementation GYPerson (Extend)
int weight_;

- (void)setWeight:(int)weight {
    weight_ = weight;
}

- (int)weight {
    return weight_;
}
@end

GYPerson *person = [[GYPerson alloc] init];
person.weight = 20;
NSLog(@"%@", @(person.weight));

通过赋值打印,可以得出理想结果。但是,如果其他对象赋值,会重新覆盖值

    GYPerson *person = [[GYPerson alloc] init];
    person.weight = 20; //输出20
   
    GYPerson *person1 = [[GYPerson alloc] init];
    person1.weight = 50;
    NSLog(@"%@", @(person.weight)); // 输出50

所以该方法不可取

方法2使用字典存储值,保证每个对象的赋值都有唯一存储地址。


NSMutableDictionary *weightsMuDict;
+ (void)load {
    //保证只初始化一次
    weightsMuDict = [NSMutableDictionary dictionary];
}

- (void)setWeight:(int)weight {
    NSString *key = [NSString stringWithFormat:@"%p", self];
    weightsMuDict[key] = @(weight);
}

- (int)weight {
    NSString *key = [NSString stringWithFormat:@"%p", self];
    return [weightsMuDict[key] intValue];
}

@end

但是该方法可能存在线程安全的问题。

方法3使用Runtime中API方法关联对象

static const int weightKey;

- (void)setWeight:(int)weight {
    objc_setAssociatedObject(self, &weightKey, @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight {
    return [objc_getAssociatedObject(self, &weightKey) intValue];
}

//其他写法
- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    return objc_getAssociatedObject(self, @selector(name));
 //隐式参数 _cmd = @selector(name)
 //return objc_getAssociatedObject(self, _cmd);
}

Tip:
1.关联对象并不是存储在被关联对象本身内存中。
2.关联对象存储在一个全局的Associations Manager中
3.设置关联对象为nil,就相当于移除对象。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容