07.Objective-C 关联对象
2021-02-07 本文已影响0人
ProfessorFan
问题
- 分类中可以添加属性吗?
- 整么才能使分类中的属性,像正常类的属性一样使用?
- 关联对象的本质
答案
- 分类中可以添加属性吗?
答案是肯定得分类中肯定可以添加属性,只是在分类中添加属性,不会向正常类中添加属性一样,自动生成实例变量,还有setter,get 方法
struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods;
const struct _method_list_t *class_methods;
const struct _protocol_list_t *protocols;
const struct _prop_list_t *properties; # 这个就是分类的结构,里面存在属性这个list
};
- 整么才能使分类中的属性,像正常类的属性一样使用?
但是是关联对象,可以使分类中有向类一样的正常属性
具体代码如下:
# 这个是分类的 interface
@interface FanPerson(Test)
@property (copy, nonatomic) NSString *name;
@end
# 这个是分类的implement
@implement FanPerson(Test)
- (void)setName:(NSString *)name
{
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name
{
// 隐式参数
// _cmd == @selector(name)
return objc_getAssociatedObject(self, _cmd);
}
@end
- 关联对象的本质
- 关联对象涉及到的核心对象有:
AssociationsManager,AssociationsHashMap,ObjectAssociationMap,ObjecAssociation 这四个对象
关键类的在objc 源码中的定义:
class AssociationsManager {
using Storage = ExplicitInitDenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap>;
static Storage _mapStorage;
public:
AssociationsManager() { AssociationsManagerLock.lock(); }
~AssociationsManager() { AssociationsManagerLock.unlock(); }
AssociationsHashMap &get() {
return _mapStorage.get();
}
static void init() {
_mapStorage.init();
}
};
typedef DenseMap<const void *, ObjcAssociation> ObjectAssociationMap;
typedef DenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap> AssociationsHashMap;
class ObjcAssociation {
uintptr_t _policy;
id _value;
}
-
关联对象原理图
IOS关联对象原理图.png