跳转到内容

编译器构造/Objective-C

来自维基教科书,开放的书籍,开放的世界

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——它无法生成发送消息的代码,因为返回浮点值通常与返回整数值不同。

华夏公益教科书