OC學習筆記 id類型


id是oc語言中一個獨特的數據類型。一種通用對象類型。可以轉換為任何數據類型,即id類型的變量可以存放任何數據類型的對象。

萬能指針,能指向操作任何OC對象 id ==NSObject *

這是為什么呢?還是從OC的內部實現機制上來分析吧!

         在內部處理上,id類型被定義為指向對象的指針,這可以從id的定義中看出。id在objc.h中的定義為:

1 typedef struct objc_object {
2     Class isa;
3 } *id;

而Class為typedef struct objc_class *Class,即Class為struct objc_class的指針別名,而objc_class在runtime.h中的定義為

 1 struct objc_class {
 2     Class isa;
 3 #if !__OBJC2__
 4     Class super_class                                        OBJC2_UNAVAILABLE;
 5     const char *name                                         OBJC2_UNAVAILABLE;
 6     long version                                             OBJC2_UNAVAILABLE;
 7     long info                                                OBJC2_UNAVAILABLE;
 8     long instance_size                                       OBJC2_UNAVAILABLE;
 9     struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
10     struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
11     struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
12     struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
13 #endif
14 
15 } OBJC2_UNAVAILABLE;

從上面的代碼看出,id是指向objc_object的一個指針。那么它為什么可以指向NSObject對象呢?還是看NSObject的定義吧!

1 @interface NSObject <NSObject> {
2     Class    isa;
3 }

可以看出NSObject只有一個Class對象isa,而objc_object也是只有一個Class對象isa,可以看成兩者等價(不知道對不對?)。所以id是一個一個比較靈活的對象指針,並且是一個指向任何一個繼承了Object(或者NSObject)類的對象。而在cocoa的開發環境里,NSObject是所有類的根類。所以id可以指向任何一個cocoa的合法對象。

從上面的代碼分析可以看出,id實際上是一個指向NSObjec對象的實例變量的指針,即id和void*並非完全一樣。

 

PS:id和IMP標志符之間的關系:

    id:是一種數據類型;

    IMP:指向返回id類型值的方法的指針,而且指向的方法帶有self和selector對象作為第一個參數。它是一種C類型,可以認為是一種函數指針。其英文解釋:IMP is a C type referring to the implementation of a method, also known as an implementation pointer. It's a pointer to a function returning id, and with self and a method selector (available inside method definitions as the variable _cmd) as the first arguments。

其使用方法為:id (*IMP)(id, SEL, ...);(SEL為選擇器selector的一個類型,選擇器就是指向方法的一個指針)

對於NSObject對象,你可以這樣來獲得一個給定方法的IMP:
IMP imp=[obj methodForSelector:@selector(message)];
對於任意的對象object,
IMP imp=[obj methodFor:@selector(message)];

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM