跳轉到內容

編譯器構造/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——它無法生成傳送訊息的程式碼,因為返回浮點值通常與返回整數值不同。

華夏公益教科書