2013-01-08 23 views
3

我最近在這裏讀到,一個objective-c對象作爲一個結構體存儲在堆上。該結構包含對象iVars,繼承的iVars和isa指針。在運行時objective-c如何處理方法解析?

我試圖弄清楚當我發送消息到這個對象時,運行時如何計算代碼運行?

我知道每個類都有一個類對象。這是否也存儲在堆上?

我認爲它的工作方式是運行時從結構中獲取isa指針,用它來調用類對象上的消息。它是否正確?

+0

http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html –

+0

我不知道細節,但每個Cocoa對象都包含一個指向它的指針類對象。每個類對象都包含一些概念上類似於NSDictionary的東西,可以用它來查找方法實現,並給出它們的名稱。每次你調用一個方法(「發送消息」)時,這個機制被用來查找實現(雖然該方案當然是高度優化的,並且具有緩存等)。 (請注意,這與C++和Java不同,在C++和Java中,只需將大部分「虛擬」方法調用用於靜態表索引。) –

回答

11

簡而言之,每個Objective-C實例都有一個指向其類的指針。該類包含一個元數據清單,其中包含該類實現的所有方法。當一個消息被髮送到一個對象 - 當一個方法被調用時 - 運行時使用指向該類的指針來查找該方法的名稱並調用它,如果可以找到的話。如果找不到,運行時會查找超類(它是每個類的元數據的一部分),並繼承NSObject的繼承鏈。如果最終找不到方法,則運行時會經歷一系列最後的努力,以查看它們是否是替代處理程序,並最終引發異常,如果不是。

如果你想得到更多的細節,我寫了一個multipart tour of exactly how Objective-C method dispatch works.它稍微過時 - 不處理ARC,標記指針或塊作爲IMP - 但仍然完全適用。


是的,類存儲在堆中,但通常不在malloc()d內存中。類通常作爲只讀,共享和內存加載。也就是說,對於在系統上運行的所有應用程序,在內存中只有NSString類的副本。您可以動態地創建類,這些類將在常規堆中,但它是非典型的。

相關問題