为了帮助运行时系统,编译器将每个方法中的返回值类型和参数类型进行编码,并将方法名和方法选择器进行关联。编译器通过@encode()指令编译每个方法。 当给定类型规范时,@encode()返回一个编码该类型的字符串。 这个类型可以是一个基本的类型,比如int,指针,带标签的结构体(a tagged structure)或联合体(union),或者是一个类名。实际上,这些类型可以作为C 语言中sizeof()函数的参数。
char *buf1 = @encode(int **);
char *buf2 = @encode(struct key);
char *buf3 = @encode(Rectangle);
Objective-C类型编码表1:
| Code | Meaning |
|---|---|
| c | A char |
| d | A double |
| f | A float |
| i | An int |
| s | A short |
| l | A long |
| q | A long long |
| B | A C++ bool or a C99 _Bool |
| C | An unsigned char |
| I | An unsigned int |
| L | An unsigned long |
| S | An unsigned short |
| Q | An unsigned long long |
| 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相同。
数组的类型编码格式:[number type]
其中:number 为数组中元素个数,type为数组元素的类型
//由12个浮点类型元素构成的数组编码
[12f]
//由6个整数类型指针元素构成的数组编码
[6^i]
结构体的类型编码格式:{name=type...}
其中:name为结构体类型名,type为结构体元素类型
//结构体
typedef struct example {
id anObject;
char *aString;
int anInt;
float aFloat;
} Example;
//结构体Example的编码
{example=@*if}
//结构体指针
struct example *objc1;
Example *objc2;
//结构体指针objc1,objc2的编码
^{example=@*if}
对象被视为结构。 例如,将NSObject类名称传递给@encode()会产生以下编码:
{NSObject=#}
NSObject类只声明一个Class类型的实例变量isa。
请注意,尽管@encode()指令不返回它们,但是当它们用于在协议中声明方法时,运行时系统使用表2中列出的其他编码作为类型限定符。
Objective-C方法编码表2:
| Code | Meaning |
|---|---|
| r | const |
| n | in |
| N | inout |
| o | out |
| O | bycopy |
| R | byref |
| V | oneway |