OC 底層原理之類結構的分析

2021-10-09 14:59:44 字數 4350 閱讀 3208

今天我們經過原始碼的探索來分析下類的結構,我們從isa類的繼承兩方面來分析:

我們先看乙個經典的走位圖:

我們來驗證下isa的走位:

首先我們先建立乙個lgperson類然後用lldb列印一驗證:

@inte***ce lgperson : nsobject

@end

intmain

(int argc,

const

char

* ar**)

isa總結:物件的isa 指向物件的類--> 物件的類的isa指向元類 ---> 元類的isa指向根元類 ---> 根元類的isa指向自己從上面的經典走位圖裡面我們也可以看出元類的繼承關係:

繼承於父類父類繼承於根類根類繼承於nil

元類繼承於父元類父元類繼承於根元類根元類繼承於根類根類繼承於nil

: 關於類的繼承我們要明白一點:例項物件之間是沒有繼承關係的,只有類 之間才有繼承關係

通過下面的圖我們也可以看到例項物件之間是沒有繼承關係的

我們在上面的走位圖中發現,物件元類中都有isa,這是為什麼呢? 這就引出了兩個結構體_objc_class_objc_object,我們對mian.m進行clang編譯後我們會發現物件本質是乙個結構體,他的底層會被編譯為nsobject_impl而 這個nsobject_impl,內部包含乙個class 定義的 isa,而class 是有 objc_class 定義的

struct lgperson_impl 

;struct nsobject_impl

;typedef

struct objc_class *class;

我們在原始碼中搜尋objc_class,發現objc_class繼承於_objc_object,而_objc_object裡面包含乙個預設的isa:

struct objc_class : objc_object 

}struct objc_class

從上面的原始碼我們也看出了,所有的物件都是從objc_object繼承過來的,所以都一定有isa.

我們先建立乙個lgperson類,然後為它新增屬性成員變數例項方法類方法都存在類資訊的那個部位:

@inte***ce lgperson : nsobject 

@property

(nonatomic, strong) nsstring *name;-(

void

)sayhello;+(

void

@end

@implementation lgperson-(

void

)sayhello+(

void

nslog()

;}@end

探索之前我們先看下類資訊裡面都包含哪些東西:

struct objc_class : objc_object 

}

我們看到bits是儲存類的資訊的,而bits是有class_data_bits_t定義的,那我們就看下class_data_bits_t的原始碼:

struct class_data_bits_t 

// **自動省略

}const class_ro_t *

safe_ro()

else

}// **自動省略

我們主要看下class_rw_tclass_ro_t:

struct class_rw_t 

const property_array_t properties()

const

const protocol_array_t protocols()

const

}

我們現在用lldb來列印下bits裡面的資訊:

總結:

我們來根據一段**來驗證一下:

//mark: - 分析類物件記憶體存在個數

void

lgtestclassnum()

看下列印結果:

發現這個幾個class 的位址都是一樣的,說明類在記憶體裡面只存在乙份

objc_class 與 objc_object 有什麼關係?

結構體型別objc_class繼承自objc_object型別,其中objc_object也是乙個結構體,且有乙個isa屬性,所以objc_class也擁有了isa屬性

objc_object 與 物件的關係?

所有的物件都來自nsobject,但他們的底層都是來自objc_object,所以物件objc_object是繼承關係

Mybatis的底層原理分析

在分析底層原理之前,先看單獨使用mybatis時的執行流程 public class mybatistest 6.釋放資源 sqlsession.close is.close 以下是我通過debug除錯得到的結果 拋開我們使用mybatis時這幾步執行流程來說,在mybatis底層最重要的兩個物件就...

class底層原理分析

class 類名 會把類構造出來 實際上是 元類例項化產生類 這個物件 類例項化產生物件,一定是 類名 person 類是由type例項化產生,傳一堆引數 type 呼叫類的 init 方法 type type object or name,bases,dict object or name 類的名...

iOS底層原理總結 OC方法的本質

int main int argc,const char argv return 0 可以看出在我們進行lgperson初始化的時候,我們都知道會呼叫alloc,init.我這裡為了簡單只呼叫 new 但是底層不是像我們利用呼叫的,而是呼叫了乙個函式objc msgsend這就是我們訊息傳送的方法,...