编译器构造/Objective-C
外观
< 编译器构造
在 Objective-C 中,每个类都是 C 中的结构体。也就是说,
@interface A { int a, b, c } @end
将被实现为
struct A { int a, b, c; .... // some runtime information };
因此,由于 Objective-C 中的每个对象都是指向堆中内存块的指针。因此,访问字段的方式与访问结构体成员的方式相同。也就是说,
id obj = [A alloc];
这种方案的含义是,虽然对象自然适合非 OOP C 程序,但缺点是字段不能被“隐藏”。也就是说,
@interface A { @private int a; } @end @interface B : A { @private int a; } @end
这将导致重复成员错误。这与 Java 中的情况形成对比。
最后,由于方法的选择是在运行时发生的(与 Java 或 C++ 中的情况相反),方法的处理方式与字段不同。
在 Objective-C 中,方法的选择是在运行时发生的。编译器可能会发出关于可能拼写错误的名称的警告,因为编译器可以知道程序中定义的一组选择器名称。但是,这在语义上不是必需的;任何消息都可以发送到任何对象。
在语义上,消息的发送者会检查给定对象是否响应该消息,如果否,则尝试其超类,如果仍然否,则尝试其超类等等。
例如,当有两个返回类型不同的选择器时,可能会出现复杂情况。考虑以下情况。
@interface A { } - (float) func: (int) i @end @interface B { } - (int) func: (int) i @end
在这种情况下,由于编译器无法知道对象将响应哪种方法——(float) func 或 (int) func——它无法生成发送消息的代码,因为返回浮点值通常与返回整数值不同。