类型编码
为了协助 runtime 系统,编译器将吧参数和返回值编码为字符串,并把这个字符串和方法选择器关联起来。在其他上下文中,这种编码方案同样适用,可以用 @encode() 来告知编译器,当编译器被给定一种类型的规范的时候,@encode() 将返回这个类型的字符串编码,这些可以是基础类型,int,指针,结构体,联合体,或者一个类名,事实上,这些都可以被用作 sizeof() 的参数。
char *buf1 = @encode(int **);
char *buf2 = @encode(struct key);
char *buf3 = @encode(Rectangle);
下边这个表列举了类型编码,当一个对象归档或者分配的时候,有很多代码是重复的。当你解档或者归档的时候,这写列出来的代码,有的能用,有的不能用。你能用那些不是由 @encode() 生成的。更多关于对象的归档和分配的信息详见NSCoder。
| Code | Meaning |
|---|---|
| c | A char |
| i | A int |
| s | A short |
| l | A long l is treated as a 32-bit quantity on 64-bit programs. |
| q | A long long |
| C | A unsigned char |
| I | A unsigned int |
| S | A unsigned short |
| L | A unsigned long |
| Q | A 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}
不管传递给 @encode() 的是重新定义的名字 Example 还是结构体标记 example 返回的编码都是一样的,结构体指针携带了同样的关于结构体作用域的信息。
^{example=@*i}
但是,其他级别的就移除了内部细节
^^{example}
对象和结构体一样,给 @encode() 传递一个对象回的到这样的
{NSObject=#}
NSObject 类只定义了一个实例变量 isa
尽管 @encode() 不返回详细信息,当你使用定义在协议中的方法的时候,runtime 系统提供了一个附加类型的表。
| Code | Meaning |
|---|---|
| r | const |
| n | nil |
| N | inout |
| o | out |
| O | bycopy |
| R | byref |
| V | onewey |