2014-03-27 56 views
0

我一直聽到Objective-C類只是C結構。任何人都可以更多地瞭解它們是如何實現的?Objective-C類是如何實現的?

+0

沒什麼特別的。具有一組方法的C結構。每個方法都是在參數中具有指向該結構和方法選擇器的指針的函數。 –

回答

4

我一直聽到Objective-C類只是C結構。

讓我們先談論對象。

對象不是只是結構。它們是具有特定佈局的結構,Objective-C編譯器和運行時可以理解它。運行時提供了一堆C函數來實現消息傳遞等功能。編譯器將Objective-C語法轉換爲對這些運行時函數的調用。因此,Objective-C中的一個片段,它看起來像這樣:

[foo bar:baz]; 

可能會轉換成等價的C代碼:

objc_msgSend(foo, sel_bar, baz); 

其中sel_bar是對應於bar:選擇。 foo是指向一個對象,那就是形式的結構:

struct objc_object { 
    Class isa; 
}; 

有可能是其他的實例變量搭載在該結構的頂部,所以在foo的結構也許真的是這樣的:

struct objc_object { 
    Class isa; 
    int a; 
    float b; 
    id c; 
}; 

但是,作爲運行時可以使用的對象,結構實際上只需要一個isa指針作爲它的第一個成員。這指向一個類對象,它定義foo所屬的類。

現在,一個類也是一個對象 - 也就是說,它是一個以isa指針開頭的結構。但是類有附加字段,包括超類,類名,實例變量列表,方法列表等等。你可以在objc_class.h中看到實際的定義。查看Objective-C Runtime Reference以查看對類進行操作的函數列表,以更好地瞭解運行時如何操作該結構。

關於Objective-C如何用結構創建對象有很多知識,但Apple提供了一個解釋它的完整文檔,所以我只是將您引用到Objective-C Runtime Programming Guide

3

直接實例變量存儲看起來很像C結構;通常它是一個,你可以直接操縱結構而不是對象。這已被刪除。

所以在結構,你將有:

  • isa指針,它指向元類;
  • 分配對象內的偏移量記錄到這個元類的結構成員的開始(這是如何避免脆弱的基類問題 - 在應用程序加載時適當地存儲和添加大小);和
  • 所有直接實例變量的類似結構的字段。

在別處在運行時也將有至少從映射:

  • 元類IMP lementations用於每個受支持選擇的方法;
  • 該實例爲存儲所有動態屬性;
  • 該實例爲關聯對象;和
  • 也可能從實例到任何weak引用它。

此外還有一個保留計數的哈希映射。保留計數僅在高於1時存儲 - 隱含第一個保留。

很多標記爲指針的異常。 64位運行時允許非常小的對象完全填充到指針中。所以指針就是對象存儲;運行時可以發現真正的指針和祕密是對象的指針之間的差異,因爲有效的指針具有對齊要求。