Objective C 中的類和物件

2021-09-07 07:23:35 字數 4095 閱讀 1365

在objc4-532.2以後,蘋果把nsobject的實現也挪進來了。想要了解nsobject底層實現終於不用去摳gnustep了~

好了,下面正文:

runtime裡面,宣告了id和class的型別,簡化一下如下:

1

2

3

4

5

6

7

8

9

structobjc_class;

structobjc_object;

typedefstructobjc_class *class;//類  (class object)

typedefstructobjc_object *id;//物件 (instance of class)

在objc中,id代表了乙個物件。根據上面的宣告,凡是首位址是*isa的struct指標,都可以被認為是objc中的物件。執行時可以通過isa指標,查詢到該物件是屬於什麼類(class)。

根據上面的說法,類物件(class)同樣也算是物件,那它的isa又是指向了什麼呢?為了了解這些東西是怎麼回事,這裡寫乙個簡單的類nyancat,並且用c重寫一遍,看看編譯器在底層到底是如何實現的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@inte***cenyancat : nsobject

-(void)nyan;

+(void)nyan;

@end

@implementationnyancat

-(void)nyan1

+(void)nyan2

@end

上面是乙個簡單的類,有兩個instance variable,有乙個類方法、乙個例項方法。

1

clang-rewrite-objc nyancat.m

在終端執行上面這一條語句,讓clang將該類重寫為cpp**,我們就能檢視到大概底層的實現機制了(實際編譯的檔案和這個會有些出入,不同目標架構和不同版本clang也會有不同..權且當參考了)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

//class的實際結構

struct_class_t;

//class包含的資訊

struct_class_ro_t;

//nyancat(meta-class)

struct_class_t objc_metaclass_$_nyancat=;

//nyancat(class)

struct_class_t objc_class_$_nyancat=;

typedefstructobjc_object nyancat;//定義nyancat型別

//更詳細的不貼**了..

所有nyancat的例項的isa都指向了nyancat(class)。

nyancat(class)是乙個全域性變數,其中記錄了類名、成員變數資訊、property資訊、protocol資訊和例項方法列表等。

nyancat(class)的isa指向了全域性變數nyancat(meta-class),meta-class裡只記錄了類名、類方法列表等。

畫出圖來就是這樣:

舉例來說一下:

1

2

nyancat*cat=[[nyancatalloc]init];

[cat nyan1];

向cat (instance) 傳送訊息nyan1時,執行時會通過isa指標查詢到nyancat(class),這裡儲存著本類中定義的例項方法的指標。

1

[nyancatnyan2];

向nyancat(class)傳送訊息nyan2時,執行時會通過isa查詢到nyancat(meta-class),這裡儲存著本類中定義的類方法的指標。

執行時如何利用chass和meta-class來實現動態訊息的,以後在記吧~

在_class_t裡面,第二個成員是superclass,很明顯這個指標指向了它的父類。執行時可以通過isa和superclass獲取乙個類在繼承樹上的完整資訊。

為了說明方便,這裡把上面的例子稍微改一下:nyancat : cat : nsobject 這樣乙個繼承樹,畫出圖來就是這樣子的:

如上面圖中,跟隨黑線,可以看到isa的指向。執行時,每個物件的isa都不為空,這樣只要是乙個id型別的物件,runtime都可以通過訪問首位址偏移(isa)來獲取該物件的資訊了。

上圖中跟隨綠線,可以看到superclass的指向。當執行時在搜尋方法、ivar資訊時,如果沒有找到資訊,則會沿superclass的線查詢上去,最終nsobject(根類)的superclass是nil。

如果自己定義了乙個根類(比如nsproxy),則這個根類會替換圖中nsobject的位置。

為了驗證上面的說法,可以敲一下**看看:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#import "nyancat.h"

#import

#import

voidtest()

最後吐嘈一下:平時開發時,meta-class基本是用不著接觸的,superclass指標無法訪問,isa指標可能稍後也會隱藏起來(蘋果的動作真多)。。所以上面說得這些,了解一下就好~~

iOS學習筆記 Objective C 類和物件

inte ce myclass nsobject 方法宣告 id initwithstring nsstring aname myclass createmywithstring nsstring aname end在類的介面完成 h 定義乙個類 新增類的屬性 新增類的行為 方法 inte ce p...

Objective C物件之類物件和元類物件

作為c語言的超集,物件導向成為objective c與c語言的最大區別,因此,物件是objective c中最重要的部分之一。目前物件導向的語言有很多,objective c中的物件又和其他語言中的物件有什麼區別呢?下面來簡單介紹objective c中物件的實現。1 objective c中的類 ...

關於objective c中類的組合

關於objective c中類的組合問題,我們先來看一道題 1.設計2個類,類之間的關係自擬 比如繼承 組合 1 身材資料 1 屬性 身高 體重 手長 腳長 2 方法 屬性相應的set和get方法 2 人 1 屬性 年齡 身高 體重 手長 腳長 2 方法 屬性相應的set和get方法 思路 在這道題...