標籤: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