关联属性的相关方法及优缺点
方法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,就相当于移除对象。
网友评论