iOS:关联对象
2019-12-22 本文已影响0人
码小菜
目录
一,添加属性
二,基本知识
三,底层原理
四,注意点
一,添加属性
1,在类中添加属性,系统会自动生成带下划线的成员变量、get/set
方法的声明和实现
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
- (NSString *)name;
- (void)setName:(NSString *)name;
@end
@implementation Person
- (NSString *)name {
return _name;
}
- (void)setName:(NSString *)name {
_name = name;
}
@end
2,在分类中添加属性,系统会自动生成get/set
方法的声明,不会生成带下划线的成员变量和get/set
方法的实现
@interface Person (Add1)
@property (nonatomic, assign) NSInteger age;
- (NSInteger)age;
- (void)setAge:(NSInteger)age;
@end
@implementation Person (Add1)
@end
3,直接使用分类中的属性会crash,必须手动实现get/set
方法
Person *person = [Person new];
person.name = @"111";
person.age = 1; // crash
NSLog(@"%@---%zd", person.name, person.age);
// 打印
-[Person setAge:]: unrecognized selector sent to instance 0x6000022d72b0
二,基本知识
1,介绍
- 添加关联对象
// 将value与object关联起来,key为关联键值,policy为关联策略
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy);
- 获取关联对象
// 用key从object中取出value
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key);
- 移除所有关联对象
// 移除与object关联的所有对象
OBJC_EXPORT void
objc_removeAssociatedObjects(id _Nonnull object);
2,策略
objc_AssociationPolicy | 修饰符 |
---|---|
OBJC_ASSOCIATION_ASSIGN | assign |
OBJC_ASSOCIATION_RETAIN | strong,atomic |
OBJC_ASSOCIATION_COPY | copy,atomic |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | strong,nonatomic |
OBJC_ASSOCIATION_COPY_NONATOMIC | copy,nonatomic |
3,使用
@implementation Person (Add1)
- (NSInteger)age {
return [objc_getAssociatedObject(self, @selector(age)) integerValue];
}
- (void)setAge:(NSInteger)age {
objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
三,底层原理
1,核心对象
AssociationsManager
class AssociationsManager {
static AssociationsHashMap *_map;
};
AssociationsHashMap
class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap *>
ObjectAssociationMap
class ObjectAssociationMap : public std::map<void *, ObjcAssociation>
ObjcAssociation
class ObjcAssociation {
uintptr_t _policy;
id _value;
};
2,对象间的关系
-
AssociationsManager
(对象):含有一个AssociationsHashMap
类型的变量 -
AssociationsHashMap
(表):传入的object
为key,ObjectAssociationMap
为value -
ObjectAssociationMap
(表):传入的key
为key,ObjcAssociation
为value -
ObjcAssociation
(对象):存储传入的policy
和value
四,注意点
1, 设置关联对象为nil
,就相当于移除该关联对象
objc_setAssociatedObject(self, @selector(age), nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
2,关联对象value
并不存储在被关联对象object
的内存中,而是存储在全局统一的AssociationsManager
中