最近想重新充下電, 鞏固下基礎(chǔ), 把以前學過的東西再重新整理一遍, 我是搬運工, 懂得都懂
在arm64架構(gòu)之前砌滞,isa就是一個普通的指針,存儲著Class念链、Meta-Class對象的內(nèi)存地址
從arm64架構(gòu)開始盼忌,對isa進行了優(yōu)化: 變成了一個共用體(union)結(jié)構(gòu)积糯,還使用位域來存儲更多的信息, 共用體中的變量都公共一塊內(nèi)存
union isa_t
{
Class cls;
uintptr_t bits;
// 該結(jié)構(gòu)體只是為了增加可讀性
// 一共64位
struct {
uintptr_t nonpointer : 1; // 占1位
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33; // 占33位
uintptr_t magic : 6; // 占6位
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 19; // 占19位
}
};
isa中存儲的信息
名稱 | 用途 |
---|---|
nonpointer | 0:代表普通的指針,存儲著Class碴犬、Meta-Class對象的內(nèi)存地址 1:代表優(yōu)化過絮宁,使用位域存儲更多的信息 |
has_assoc | 是否有設(shè)置過關(guān)聯(lián)對象,如果沒有服协,釋放時會更快 |
has_cxx_dtor | 是否有C++的析構(gòu)函數(shù)(.cxx_destruct)绍昂,如果沒有,釋放時會更快 |
shiftcls | 存儲著Class偿荷、Meta-Class對象的內(nèi)存地址信息 |
magic | 用于在調(diào)試時分辨對象是否未完成初始化 |
weakly_referenced | 是否有被弱引用指向過(指向過,不是正在指向)窘游,如果沒有,釋放時會更快 |
deallocating | 對象是否正在釋放 |
extra_rc | 里面存儲的值是引用計數(shù)器減1 |
has_sidetable_rc | 引用計數(shù)器是否過大無法存儲在isa中 如果為1跳纳,那么引用計數(shù)會存儲在一個叫SideTable的類的屬性中 |
以實例對象通過isa查找類對象的過程為例子
得到實例對象的isa共用體中的shiftcls中的數(shù)據(jù), 然后通過 (& ISA_MASK) 的位運算 得到 類/元類對象的地址值
ps: 類和元類對象的地址值后三位 一定是000, 這是由 ISA_MASK決定的
經(jīng)典流程圖
總結(jié)
instance的isa指向class
class的isa指向meta-class
meta-class的isa指向基類的meta-class
class的superclass指向父類的class
如果沒有父類忍饰,superclass指針為nil
meta-class的superclass指向父類的meta-class
基類的meta-class的superclass指向基類的class
instance調(diào)用對象方法的軌跡
isa找到class,方法不存在寺庄,就通過superclass找父類
class調(diào)用類方法的軌跡
isa找meta-class艾蓝,方法不存在,就通過superclass找父類
如果找不到 會報 unrecognized selector sent to instance .... 的錯誤
arm64之后 isa不會直接指向 class 或者 meta-class, 而是經(jīng)過一次位運算得到的