[0] outline
-- [1] id和class
-- [2] 動態地操作類
-- [3] 例項化
[1] id和class
在objective-c中有乙個特別的資料型別作為物件識別符號:id,可以指向任何型別的物件。
通過 「可以指向任何型別的物件」 這一描述,猜想id實際上是指向objective-c物件系統中的基類(繼承體系中的祖先結構)的指標,在執行時是指向物件記憶體布局的基類部分。
第一眼看到id資料型別,我聯想到了python中的pyobject結構:
[cpp]view plain
copy
typedef
struct
_object pyobject;
該資料型別也是python物件系統中的祖先型別,不過與id相對應的應該是pyobject *型別。
id資料型別是乙個指向
structobjc_object結構的指標:
[cpp]view plain
copy
typedef
struct
objc_class *class;
typedef
struct
objc_object *id;
更確切地說,id是指向class型別的指標,而class又是指向structobjc_class結構的指標:
[cpp]view plain
copy
struct
objc_class ;
至此,可以看到objective-c物件系統的基石:structobjc_class結構:
[cpp]view plain
copy
isa指標:指向該物件所屬型別的型別物件(class object)。在objective-c中,類也是用物件來表示的,而類的isa指標指向它的metaclass(儲存靜態成員變數和類方法)。
super_class指標:指向父類。
name:類名稱。
version:類的版本資訊。
info:執行期使用的標誌位,比如0x1(cls_class)表示該類為普通class
,0x2(cls_meta)表示該類為 metaclass。
instance_size:例項大小,即記憶體所佔空間。
ivars:指向成員變數列表的指標。
methodlists:根據標誌位的不同可能指向不同,比如可能指向例項方法列表,或者指向類方法列表。
cache:因為objective-c的訊息**需要查詢dispatch table甚至可能需要遍歷繼承體系,所以快取最近使用的方法。
protocols:類需要遵守的協議。
[2] 動態地操作類
由上知道了類也是一種物件,那麼類物件也有一種型別,這種型別就是類的metaclass
,因此類方法其實就是metaclass的成員方法,類和metaclass是配套出現的。
那麼metaclass的isa指標和super_class指標怎麼指向的呢?
如果metaclass對應基類,那麼它的isa指向自身、super_class指標指向對應的類(基類);如果不是則isa指標指向基類的metaclass、super_class指標指向父類的metaclass。
基類的isa指標為nil。
這不禁讓我又想起了python中類似的設計思想,比如整型數字2的型別是pyintobject,而pyintobject類的型別是pytypeobject,pytypeobject的型別是pytypeobject。最終止於此。
同樣地,python中也有metaclass的存在。
知道了類的表示結構,我們可以動態地對類進行操作,加深理解。
[cpp]view plain
copy
//// main.m
// hellooc
//// created by jason lee on 12-2-17.
//#import
#import
#import
void
selfintro(idself, sel_cmd);
intmain (
intargc, constchar * argv)
object_setinstancevariable(demo, "myvar"
, nil);
void
*outvalue = (
void
*)0x1;
object_getinstancevariable(demo, "myvar"
, &outvalue);
if(nil == outvalue)
object_dispose(demo);
} return0;
} void
selfintro(idself, sel_cmd)
nslog(@"%p, %@"
, isa, objc_getmetaclass(class_getname([isa
class
])));
isa = isa->isa; //then, isa is assigned to nsdemo's metaclass
} }
[3] 例項化
要例項化出乙個物件,需要根據類的定義來進行。類的定義包括類名稱、資料和運算元據的方法。
編譯過程,類的資訊會被記錄下來,供runtime system使用,同時編譯器會為每個類建立唯一的乙個物件來表示它:class object。如果從功能上說,class object也是factory object,它能夠執行類方法,負責建立例項。
從這個角度來看,我在思考class object是否就是metaclass,但是不能確認。
」,但metaclass並不能作為例項原型。
於是我認為class object是執行時class和metaclass結合起來的受限表現,能夠訪問編譯器捕捉下來的類資訊,沒有成員變數,不能呼叫成員方法,但是可以執行類方法。
從原始碼層次來看,class object是由類名來表示,比如下述**中:
[cpp]view plain
copy
intversion = [nsstring version];
nsstring代表著class object。
首先,class object會被runtime system傳送initialize訊息進行初始化,讓其做好執行時的準備,比如初始化靜態變數。
之後,可以呼叫class object的方法(類方法)alloc來為新的例項物件分配記憶體空間,將其所有變數初始化為0,isa指標指向所屬類。
最後再呼叫init函式進行必要的初始化。
寫到這裡的時候,突然要變更辦公位置,思路被打斷了,就先寫到這裡。
最後,留乙個在so上面看到的問題,我也疑惑,只能有幾分猜測:
[這篇文章是我對so上的問題的解答:
[last updated] 2012-03-17
jason lee @ 杭州
部落格:微博:
github:
iOS開發基礎
1 乙個應用程式是怎麼啟動的?當我們基於xcode模版建立應用程式時,應用程式啟動時大部分的環境引數會被自動設定。uikit框架提供了乙個應用程式需要構建和管理它的使用者介面的所有類 啟動 結束應用程式,控制介面和觸點事件 uikit是cocoa touch提供的眾多物件導向框架中的乙個。cocoa...
IOS 開發之Object C中的物件詳解
ioswww.cppcns.com 開發之object c中的物件詳解 前言關於c語言的基礎部分已經記錄完畢,接下來就是學習object c了,編寫oc程式需要使用foundation框架。下面就是對oc中的物件介紹。物件物件和結構類似,乙個物件可以儲存多個相關的資料。在結構中,我們稱這些資料為成員...
IOS中的Swift基礎(類和物件)
person.swift import foundation 類是一類物體的共有性抽象 物件是某一類的乙個具體 class person nsobject 該方法是為了解決字典裡面的一些 key值,在該模型裡面沒有導致的系統崩潰 override func setvalue value anyobj...