當前位置:編程學習大全網 - 源碼下載 - iOS原理 isa的指向&類的繼承

iOS原理 isa的指向&類的繼承

這是壹幅很經典的圖,虛線表示『 isa的指向 』,實線表示『 類的繼承 』。通過 iOS原理 對象的本質 壹文的學習,清楚了實例對象、類對象以及元類對象的區別,接下來詳細介紹上圖中的兩個流程。

圖中的 Root class(class) 是根類,即NSObject類。 Root class(meta) 就是NSObject的元類,即根元類。從圖中可知,isa的指向如下:

從下往上分別是:

這裏創建壹個 Person 對象,然後在lldb中打印來論證這個isa的指向關系。

x/4gx 表示以16進制格式打印4段內存:

通過前面的學習,我們知道對象內存中的第壹個成員為isa,將isa和 ISA_MASK 進行與運算即可得到類對象的地址。

從打印結果可知, 實例對象的isa指向了類對象

之前有說過,類對象是在運行時由系統創建,而且只會生成壹個,這裏也在lldb中進行驗證。

$2 是通過 Person.class 方法獲取到的類對象,其地址和前面通過實例對象isa獲取到的類對象 $1 地址相同,即可證明類對象只會生成壹個。

類對象所屬的類是元類,可以通過isa成員訪問。

將類對象的isa成員和 ISA_MASK 相與後,得到的Person對象 $3 即為元類對象,即可驗證 類對象的isa指向了元類對象

通過元類對象的isa成員來訪問其所屬的類對象。

$5 是NSObject的類對象,從打印結果可以看出, $4 和 $5 的地址不相同,所以 元類對象的isa指向的不是NSObject類對象,而是NSObject的元類對象,即根元類對象

通過根類對象(NSObject類對象)的isa來訪問其所屬的類對象。

從打印結果可知, $6 和 &4 的地址相同,所以 根類對象的isa指向的是根元類對象

通過根元類對象(NSObject元類對象)的isa來訪問其所屬的類對象。

從打印結果可知, $7 和 &4 的地址相同,即 根元類對象的isa指向的是其本身

從經典圖中可知,繼承關系如下:

從這個繼承關系可知, 只有類對象和元類對象才有繼承關系,實例對象是沒有繼承關系的。且所有對象都是繼承於NSObject類對象,NSObject類對象則繼承於nil

NSObject在底層是壹個 objc_object 結構體,在objc源碼中搜索可以看到這個結構體在 objc.h 和 obje-private.h 這兩個文件中均有聲明。

在這個文件裏, objc_object 結構體裏面有壹個私有成員 isa ,是 isa_t 類型, 用於在創建對象時保存對象所屬的類的信息 ,通過將 isa 和 ISA_MASK 進行&運算,就可得到類對象的地址。

在這裏,成員isa是個 Class 類型。因為在創建對象時,在 objc_object::initIsa 裏會進行如下判斷:

若nonpointer為0,isa裏只保存類信息,即類對象的地址,所以直接聲明成 Class 類型,便於訪問。可以看到,NSObject在OC層面的結構裏,isa也是 Class 類型。

由於類(元類)對象都是繼承於NSObject類對象的,所以任何實例對象或類(元類)對象裏,都有壹個成員isa,只是 類對象的isa裏只保存了元類對象的地址,可以直接訪問元類對象,而實例對象的isa除了保存類對象的地址外,還存有引用技術等其他信息,所以若要訪問類對象,需要將實例對象的isa和 ISA_MASK 進行&運算得到類對象的地址

1. iOS原理 對象的本質

2. iOS原理 alloc核心步驟3:initInstanceIsa詳解

  • 上一篇:大話西遊看似喜劇,但到底是什麽?
  • 下一篇:mysql pxc程序要做哪些修改
  • copyright 2024編程學習大全網