第14條:理解“類對象”的用意
1. 類型信息查詢
在運(yùn)行期檢視對象類型的操作叫做“類型信息查詢”(introspection,內(nèi)省)。
*** Objective-C基礎(chǔ)知識 ***
NSString *pointerVaribel = @"Some string";
解釋:pointerVaribel變量指向NSString實例,該變量也叫指針。
typedef struct objc_object *id;
struct objc_object { Class isa; };
// 等價于
typedef sturct objc_object {
Class isa;
} *id;
解釋:該結(jié)構(gòu)體描述了Objective-C對象所用的數(shù)據(jù)結(jié)構(gòu)。其中,isa指針定義了對象所屬的類。
typedef struct objc_class *Class;
struct objc_class {
Class isa;
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;
};
解釋:該結(jié)構(gòu)體存放類的“元數(shù)據(jù)”。其中,isa指針定義了另外一個類——元類(metaclass),用來表述類對象本身所具備的元數(shù)據(jù)。super_class定義了本類的超類。
*** 類方法 *** :類方法可以理解成類對象的實例方法,每個類僅有一個“類對象”,而每個“類對象”僅有一個與之相關(guān)的“元類”。
類繼承體系 圖例

Snip20160310_5.png
總結(jié):通過這張布局關(guān)系圖即可執(zhí)行“類型信息查詢”。開發(fā)者可以查出對象是否能響應(yīng)某個選擇器,是否遵從某項協(xié)議,并且能看出此對象位于“類繼承體系”(class hierarchy)的哪一部分。
2. 在類繼承體系中查詢類型信息
*** 2.1 類型信息查詢方法 ***
可以用類型信息查詢方法來檢視類繼承體系。
“isMemberOfClass:”能夠判斷出對象是否為某個特定類的實例,而“isKindOfClass:”則能夠判斷出對象是否為某類或其派生類的實例。
*** 2.2 等同性判斷方法 ***
使用“==”操作符來比較類對象是否等同。原因在于,類對象是“單例”(singleton),在應(yīng)用程序范圍內(nèi),每個類的Class僅有一個實例,也就是說,借助“==”操作符可以精確判斷出對象是否為某類實例。如:
id object = /* ... */;
if ([object class] == [EOCSomeClass class]){
// 'object' is an instance of EOCSomeClass
}
總結(jié):應(yīng)該盡量使用類型信息查詢方法,而不應(yīng)該直接比較兩個類對象是否等同。
要點
- 每個實例都有一個指向Class對象的指針,用以表明其類型,而這些Class對象則構(gòu)成了類的繼承體系。
- 如果對象類型無法在編譯期確定,那么就應(yīng)該使用類型信息查詢方法(內(nèi)?。?/em>來探知。
- 盡量使用類型信息查詢方法來確定對象類型,而不要直接比較類對象,因為某些對象可能實現(xiàn)了消息轉(zhuǎn)發(fā)功能。