6

Objective-C は C のスーパーセットであるため、Objective-C 固有のすべてのステートメントは、.m ファイルのコンパイル中に C ステートメントに変換されます (プリプロセッサによると思います)。したがって、たとえば、次のようなメッセージ式[receiver method]は、メッセージ関数の呼び出しに変換されますobjc_msgSend(receiver, selector)

私の質問は: 次のようなクラス定義がある場合:

@interface ClassA {
    int var1;
    float var2;
    id var3;
}

-(void) method1;
-(int) method2: (int) num1;
@end

@implementation ClassA
-(void) method1 {
    // Implementation of the method
}

-(int) method2: (int) num1 {
    // Implementation of the method
}

@end

コンパイラによって何に変換されますか (Objective-C の 2.0 バージョン)? クラスを作成し、そのインスタンス変数を追加し、そのメソッドを追加し、クラスを登録するために、objc_allocateClassPair()class_addIvar()class_addMethod()などの関数の呼び出しに変換されますか(そのため、クラス構造体は、クラスとしてロードされるのではなく、実行時に実際に定義されます)。objc_registerClassPair()構造体を実行可能ファイルから)?

4

1 に答える 1

14

Objective-C は C のスーパーセットであるため、Objective-C 固有のすべてのステートメントは、.m ファイルのコンパイル中に C ステートメントに変換されます (プリプロセッサによると思います)。

それは 1988 年に当てはまりました。Objective-Cまだその方法でコンパイルできましたが、それは長い間行われていませんでした。

コンパイラは、Objective-C を C および (場合によっては) C++ と共に解析し、前処理後の出力を表す抽象構文ツリー [AST] を発行します。この AST には、さまざまな Objective-C の定義が直接的に含まれています。

GCC のコンパイルと LLVM のコンパイルの詳細が異なることに注意してください。

コンパイルされた出力を見ると、mach-o ファイル (実行可能な製品) には、クラス定義、セレクター テーブル、ivar レイアウトなどを含む Objective-C メタデータを含むファイル内のさまざまなセクションがあることがわかります。 .. コンパイラはこのメタデータを .o ファイルに生成し、リンカーはそれをすべてマッシュアップし、重複する情報 (重複するシンボルではない) を削除し、マッチョを書き込みます。

別の質問で誰かが言及したように、Objective-C リライターを使用して Objective-C をストレート C に書き換えることができますが、結果のコードは非効率的であり、規制コンパイル パイプラインとはかなり異なります。

于 2012-08-07T14:09:17.487 に答える