Objective-C的物件模型

來源:互聯網
上載者:User

標籤:blog   http   java   os   檔案   io   2014   art   

http://foredoomed.org/blog/2014/02/24/object-modeling-of-objective-c/

Objective-C是一門物件導向,並且在C的基礎上加入了Smalltalk式的訊息機制而形成的程式設計語言,它主要被蘋果公司用於開發Mac OS X和iOS作業系統。既然Objective-C是物件導向的程式設計語言,那麼我感興趣的就是對象在記憶體中是怎麼組織和表示的,訊息機制又是怎麼實現的。

0.NSObject

NSObject類和Java中的Object類有點相似,都是所有一切類的父類,也就是根類。那麼NSObject又是一個怎樣的類呢。開啟NSObject.h標頭檔就可以看到NSObject的源碼:

@interface NSObject <NSObject>{    Class isa;}

可以看到NSObject是實現了NSObject protocol的Interface,它裡面只包含了一個類型為Class的isa屬性。isa是『is a』的意思,連起來就是『is a class』,也就是說這個屬性儲存了有關類的資訊。同樣來看一下Class的源碼,它被定義在objc.h標頭檔中:

typedef struct objc_class *Class;

Class是objcclass類型,objcclass被定義在objc-class.h:

struct objc_class {              struct objc_class *isa;     struct objc_class *super_class;     const char *name;           long version;    long info;    long instance_size;    struct objc_ivar_list *ivars; #if defined(Release3CompatibilityBuild)    struct objc_method_list *methods;#else    struct objc_method_list **methodLists;#endif     struct objc_cache *cache;    struct objc_protocol_list *protocols;};

可以看到obj_class是一個結構體,它包含了所有運行時需要的有關類的資訊,包括這個類的父類是什麼類,執行個體變數,方法,協議等。有趣的是,obj_class中也有一個isa屬性,那麼它又指向哪裡呢?它指向的是一個叫做metaclass的對象,並且類型也是obj_class。所以執行個體化一個類會有兩個對象:本身和metaclass對象。這樣做的目的是把執行個體方法的資訊儲存到自己本身的類中,而把類方法儲存到metaclass類裡。那麼metaclass中的isa指向哪裡呢?因為metaclass類是沒有metaclass方法的,所有就不需要再多一個類來儲存metaclass類的方法資訊,因此,metaclass對象的isa指向自己,形成一個閉環結構。

1.訊息機制

在Objective-C中,方法的調用和其他物件導向語言(例如Java)有點區別。在Java中的方法調用可以寫成一般形式為:

object.method(argument);

但是在Objective-C裡要這樣寫:

[object method:argument];

兩者的區別是:Java的方法調用是直接調用執行個體對象的方法,而Objective-C則是發送訊息一個訊息。發送訊息的目標在編譯時間是不知道的,而是在運行時決定。方法是由selector或者SEL確定的,也就是表示方法名的字串。訊息的接收對象不能保證一定會返回結果,當這種情況發生時就會拋出異常。

編譯器會把發送訊息的語句

[receiver message]

轉換為:

objc_msgSend(receiver, selector, arg1, arg2, ...)

在objc_msgSend方法中做的是通過receiver和selector找到要調用的方法,這個方法的類型是IMP型的,然後就可以執行這個方法並把傳回值返回出去。這裡的IMP類型就是要調用方法的C語言實現,也就是一個C函數指標。

2.id

id被定義在objc.h中:

typedef struct objc_object {    Class isa;} *id;

可以看到id就是objc_object結構體,它包含了一個isa指標指向類的描述資訊,這樣的話id就可以用來動態描述類的類型了。

id的作用類似於Javascript中的var,也就是說用id關鍵字聲明的變數在編譯時間並不知道其具體類型,而是在運行時決定。因為有id關鍵字的存在,所以Objective-C就不是單純的物件導向語言,而是物件導向語言和動態語言的混合體,從這點來看Objective-C倒跟C#有點像。

參考資料

[1] Objective-C Wiki
[2] Concepts in Objective-C Programming: Object Modeling
[3] Objective-C Runtime Programming Guide

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.