為了幫助運行時系統,編譯器將每個方法的返回值類型和參數類型編碼成了字符串,并把字符串與方法選擇器關聯起來。 它使用的編碼方案在其他情況下也是有用的,因此該方案使用 @encode() 編譯器指令設置成了公共可用的。當給定一個類型說明, @encode() 會返回這個類型的字符串編碼。這個類型可以是基礎類型如 int,指針,帶標簽的結構或聯合,或者類名——實際上是可以用作C語言 sizeof() 運算符的參數的任何類型。
char *buf1 = @encode(int **);char *buf2 = @encode(struct key);char *buf3 = @encode(Rectangle);下表列出了類型編碼。注意他們中許多與你為了歸檔或分發而編碼一個對象時使用的代碼重疊了。并且,有的代碼你不能在撰寫編碼器時使用,而有的代碼你想要用于撰寫編碼器時不會由 @encode() 產生。(關于編碼對象以歸檔或分發的更多信息,參見Foundation框架參考中的 NSCoder 類說明。)
Table 6-1 Objective-C type encodings
| Code | Meaning |
|---|---|
| c | A char |
| i | An int |
| s | A short |
| l | A long l is treated as a 32-bit quantity on 64-bit PRograms. |
| q | A long long |
| C | An unsigned char |
| I | An unsigned int |
| S | An unsigned short |
| L | An unsigned long |
| Q | An unsigned long long |
| f | A float |
| d | A double |
| B | A C++ bool or a C99 _Bool |
| v | A void |
| * | A character string (char *) |
| @ | An object (whether statically typed or typed id) |
| # | A class object (Class) |
| : | A method selector (SEL) |
| [array type] | An array |
| {name=type…} | A structure |
| (name=type…) | A union |
| bnum | A bit field of num bits |
| ^type | A pointer to type |
| ? | An unknown type (among other things, this code is used for function pointers) |
重要: Objective-C 不支持 long double 類型。@encode(long double) 返回 d,跟 double 的編碼一樣。
數組的類型代碼被括在方括號之中;數組中元素的個數在左括號之后立即指出,在數組類型之前。例如,12個指向 float 的指針的數組會被編碼成:
[12^f]結構體在大括號里說明,而聯合體在圓括號里。結構體的標簽被列在最前面,接著是一個等號,然后結構體的每個字段的代碼按順序列出。例如,結構體
typedef struct example { id anObject; char *aString; int anInt;} Example;會被編碼成這樣:
{example=@*i}無論將定義的類型名稱(Example)或者結構體標簽(example)傳給 @encode() 都會返回一樣的結果。結構體指針的編碼攜帶了同樣數量的關于結構體字段的信息:
^{example=@*i}但是,另一層的間接尋址移除了內部類型說明:
^^{example}對象的處理像結構體一樣。例如,傳遞 NSObject 類名到 @encode() 會產生這樣的編碼:
{NSObject=#}NSObject 類只聲明了一個實例變量, isa,類型是Class。
注意盡管 @encode() 不直接返回它們,運行時系統還為類型修飾詞使用了額外的編碼,列在表6-2中,它們用于在協議中聲明方法。
Table 6-2 Objective-C method encodings
| Code | Meaning |
|---|---|
| r | const |
| n | in |
| N | inout |
| o | out |
| O | bycopy |
| R | byref |
| V | oneway |
新聞熱點
疑難解答