iOS底層原理 - 《Class探索》

Class定義

Class是一個objc_class * 類型結構體指針
objc_class *是Objective-C2.0版本已經廢除
在Objective-C2.0版本中,使用Class替代objc_class *

//在objc/objc.h系統文件中定義如下

typedef struct objc_class *Class;

objc_class結構體定義

理解時出現小坑.下面的定義才是2.0版本的正解
網上的博客好多都是直接截取以這個來解釋了,但是我看了OBJC_ISA_AVAILABILITY宏定義(下面有代碼片段)之后,無法理解,為什么都說廢除了,但是網上的博客好多都按照廢除的那個來解釋呢?
然后繼續查資料然后在Objective-C的runtime機制01-數據結構和內部關系圖找到了一個合理的解釋.
(其實不用懷疑,確實是2.0版本已廢除了,但是網上的博客好多都按照廢除的那個來解釋)

/// 在objc/runtime.h系統文件中定義如下

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

1、OBJC_ISA_AVAILABILITY 這里標明了已經在Objective-C2.0版本廢除了,但網上的大部分還是直接這個來解釋

用來標記isa對象是否過期有效如果是Objective-C2.0版本,就表示廢棄,否則就是依然有效.
如果是__OBJC2__版本(Objective-C第二版本),定義OBJC_ISA_AVAILABILITYattribute((deprecated))過期標記,否則就依然有效

//在objc/objc-api.h中

/* OBJC_ISA_AVAILABILITY: `isa` will be deprecated or unavailable 
* in the future */
#if !defined(OBJC_ISA_AVAILABILITY)
#   if __OBJC2__
#       define OBJC_ISA_AVAILABILITY  __attribute__((deprecated))
#   else
#       define OBJC_ISA_AVAILABILITY  /* still available */
#   endif
#endif

2、!OBJC2

表示非Object c 2.0的版本,Object c是從1.0發展到現在的2.0,這個聲明是為了兼容1.0的Object c,若是Object c 2.0的話,可見objc_class與objc_object的定義是一樣的,都是只有一個isa指針,所以說在Object c里面,類也是一個對象

objc_class結構體定義

下面??這個是蘋果官網的源碼片段objc4-680,objc_class結構體定義在OC的2.0版本定義

//-------- [file:objc-runtime-new.h] --------
struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    ......
}

//-------- [file:objc-private.h] --------
typedef struct objc_class *Class;
typedef struct objc_object *id;

struct objc_object {
private:
    isa_t isa;
    ......
}

union isa_t 
{
    ......
    Class cls;
    uintptr_t bits;
    ......
}

作者:qiushuitian
鏈接:http://www.lxweimin.com/p/50f2bcfc8fb7
  • objc_objectobjc_class關系

Runtime中定義了一個叫做 objc_object 的結構體,代表OC層的對象
定義了一個objc_class的結構體,代表OC層的,可以清楚看到, objc_class是繼承objc_object的,因此,也是一個objc_object的對象

  • objc_object中的成員變量isa

objc_object中有個isa_t 的成員變量isa,isa_t是個聯合體,我們只關心它的Class cls的聯合部分。而Class又是個objc_class *。每個對象里面有個isa的成員變量,指向它代表一個類的東西。從OC的角度看,每個對象都能從isa中尋找到它的類的相關信息。

類與元類

1.類對象(class object)
編譯器會知道類的各種信息,如類名,類屬性,類方法等等,然后在運行時,編譯器會根據類描述信息進行生成類對象(class object),這個對象是描述類信息的,是一個單例對象(singleton),這個好理解.因為整個生命周期內唯一一個類
2.元類對象(metaclass object):
類對象既然是objc_object類型,當然也有個isa的指針.這個isa指針指向的對象就是元類對象(metaclass object)。元類對象存儲的信息描述的是類對象的

其中虛線 isa指針,實線superclass

靜態描述圖

isa指針指向圖例

程序啟動之后,會根據編譯時的類的信息,在runtime環境中構建相應的類對象和元類對象。
元類對象isa都指向根類,類對象的isa指向自己的元類對象,并且是個單例,構建相應的superclass等。這樣,啟動之后,runtime就知道有些啥類,他們能干嘛,他們之間的關系是什么樣了。
運行時,如果遇到創建OC某個類的實例對象(instance object),分配空間之后,把isa指針指向對象的類對象(class object),這樣,對于這個OC對象,也就能知道類的信息。
為啥搞得那么復雜
C語言不是動態語言。OC作為C的超集,要實現動態,就要把類的描述之類的東西從編譯階段挪到運行階段。那么在運行階段,就需要有類對象(class object),元類對象(metaclass object)等等對象化的東西來處理OC類的信息。runtime就這么玩的。

參考博客:

1、Objective-C的runtime機制01-數據結構和內部關系圖[推薦閱讀]
2、iOS底層原理總結 - 探尋OC對象的本質[推薦閱讀]
3、iOS Class結構分析

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,748評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,165評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,595評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,633評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,435評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,943評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,175評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,713評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,599評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,788評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,034評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,412評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,664評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,408評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,747評論 2 370