首先我們探索來例項物件、類物件、元類之間的關係,執行下面**可以看到class1、class2、class3列印結果一樣,我們是不是可以認為類物件只有乙個,元類是乙個虛擬的類由系統幫我們建立,是類物件所屬的類,而元類歸屬是根元類,根元類的歸屬是自身。
//例項物件
person *p = [[person alloc] init];
//類物件
class class1= [person class];
class class2= p.class;
class class3= object_getclass(p);
nslog(@"\n%p-\n%p-\n%p",class1,class2,class3);
//元類物件
class class4= object_getclass(class3);
nslog(@"\n%p",class4);
//列印結果
0x10cefc148-
0x10cefc148-
0x10cefc148
0x10cefc120
為了探索類的底層,我們檢視objc原始碼可以看到objc_class繼承自objc_object,objc_object結構體裡面存在著乙個重要的屬性isa指標,isa是isa_t型別它是乙個聯合體。通過lldb命令除錯可以得出例項物件的isa指向的是它所屬的類,類物件的isa指向的是它所屬的元類,元類物件的isa指向的是根元類,根元類物件的isa指向的是根元類。根元類的父類是nsobject,nsobject的父類是nil。
struct objc_class : objc_object
void setdata(class_rw_t *newdata)
void setinfo(uint32_t set)
······
}struct objc_object
//聯合體(節省消耗的一種結構)
union isa_t
isa_t(uintptr_t value) : bits(value)
class cls;
uintptr_t bits;
#if defined(isa_bitfield)
struct ;
#endif
};// isa的初始化方法
inline class
objc_object::isa()
return (class)isa.bits;
#else
return (class)(isa.bits & isa_mask);
#endif
}
isa指標流程圖:
superclass指標流程圖:
我們的方法、屬性、協議存放在objc_class中的class_data_bits_t bits當中
struct class_rw_t
void clearflags(uint32_t clear)
// set and clear must not overlap
void changeflags(uint32_t set, uint32_t clear)
while (!osatomiccompareandswap32barrier(oldf, newf, (volatile int32_t *)&flags));}};
類結構圖如下:
iOS高階底層原理 runtime
runtime 是ios的執行時,用於實現ios載入和呼叫屬性和方法。函式中load方法沒有使用runtime機制,是底層直接呼叫的函式。load執行順序是由編譯時的檔案順序相同,先編譯的先執行load,類優先於分類的順序呼叫 load方法。initialize initialize方法是在類或類的...
iOS 底層原理之 Block
block 本質上也是乙個 oc 物件,它內部也有個 isa 指標 block 是封裝了函式呼叫以及函式呼叫環境的 oc 物件 block 的底層結構如下圖所示 原始碼解析 struct gsblock load block impl 0 block impl struct block impl g...
iOS底層原理總結 OC方法的本質
int main int argc,const char argv return 0 可以看出在我們進行lgperson初始化的時候,我們都知道會呼叫alloc,init.我這裡為了簡單只呼叫 new 但是底層不是像我們利用呼叫的,而是呼叫了乙個函式objc msgsend這就是我們訊息傳送的方法,...