一、category方法是如何添加的
- 當(dāng)編譯器編譯的時(shí)候,編譯器會(huì)將category編譯成category_t這樣的結(jié)構(gòu)體 如下:
// 分類(lèi)category底層結(jié)構(gòu)
struct _category_t {
void * isa; // NULL
const char *name; // 類(lèi)名Person
struct _class_t *cls;
const struct _method_list_t *instance_methods; // 實(shí)例方法列表
const struct _method_list_t *class_methods; // 類(lèi)方法列表
const struct _protocol_list_t *protocols; // 協(xié)議列表
const struct _prop_list_t *properties; // 屬性列表
};
-
category底層會(huì)把等類(lèi)初始化的時(shí)候,會(huì)將分類(lèi)的信息同步到class_rw_t里面,包含:method_list、property_list、protocol_list等,同步的時(shí)候會(huì)將category里面的信息添加到class的前面(而不是替換掉class里面的方法),而方法調(diào)用的時(shí)候,而是遍歷class_rw_t里面的方法,所以找到分類(lèi)里面的IMP則返回,這個(gè)流程如下:
Category.png
二、category關(guān)聯(lián)屬性
-
我們都知道category不能直接添加屬性,(原因是底層并沒(méi)有幫我們生成 對(duì)應(yīng)的 @property = ivar + getter + setter),我們需要自己用truntime的關(guān)聯(lián)方法為分類(lèi)添加屬性 那么關(guān)聯(lián)屬性的底層是怎么實(shí)現(xiàn)的呢?
objc_setAssociatedObject category A.png - 調(diào)用 void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy)
里面包含
1.AssociationsManager
{
static AssociationsHashMap *_map;
}
2.AssociationsHashMap
(
// disguised_ptr_t = DISGUISE(object)
class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap >
)
3.ObjectAssociationMap
(
// void * = key
class ObjectAssociationMap : public std::map<void *,ObjcAssociation,>
)
4.ObjcAssociation
{
// d _value =value , uintptr_t policy = uintptr_t _policy;
uintptr_t _policy;
id _value;
}
反推之獲取值的時(shí)候也是這樣獲取的

