6

Objective-Cは動的バインディングを使用します。つまり、メソッド呼び出しは実行時に解決されます。

罰金。

そして、ドット表記の使用は、実際にはメソッド呼び出しに要約されます

しかし、なぜ、私はこのようなことをすることができません:

#import <Foundation / Foundation.h>

int main(int argc、const char * argv []){
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


  //例外をインターセプトします
  @試す
  {{
    @throw [NSException
            exceptionWithName:@ "MEという名前の例外!"
            理由:@「私がしたかったので」
            userInfo:nil];
  }
  @catch(id exc)//例外オブジェクトへのポインタ?
  {{



    // NSLog(@ "%@:%@ \ n"、exc.name、exc.reason); //違法:メンバーのリクエスト
    //構造体や和集合ではないものの「名前」。。
    //Objective-cが動的バインディングとドット表記を使用する場合
    //要約すると、ゲッターを呼び出してから、
    //ここで具体的なタイプにキャストする必要があるのはなぜですか?

    //具象型NSException*にキャストした場合にのみ機能します
    NSException * nexc =(NSException *)exc;
    NSLog(@ "%@:%@ \ n"、nexc.name、nexc.reason);



  }



  [プールドレン];
    0を返します。
}

「動的バインディング」と聞くと、「スクリプト言語のように動作するはずだ」と思っていますが、JavaScriptのようなスクリプト言語と比べてObjective-Cの柔軟性が低いことに驚いています。

4

3 に答える 3

17

ランタイムとコンパイラを混同しています。ランタイムはそれに対処するのに問題はありません。問題は、ドット表記(構文糖衣構文)では、コンパイラがObjective-CオブジェクトとC構造体の間で曖昧さを解消するために型情報が必要になることです。

ドット表記を使用しない場合は、次のように機能します。

NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;

上記は、型がidでない場合に警告を生成します。これは、コンパイラが型を認識しており、ディスパッチが機能することを保証できないためですが、コンパイルして実行されます。

基本的に当面の問題は、コンパイラが構造体のロードを生成するか、Objective Cディスパッチを生成するかを知る必要があることです。つまり、ドット表記では、オブジェクトとスカラー型の違いを判断するのに十分な情報が必要です。

于 2009-11-08T17:09:03.780 に答える
17

動的バインディングは動的型付けと同義ではありません。C は厳密に型指定された言語であり、特に引数または戻り値の型は重要であり、コード生成に大きな影響を与える可能性があります。

プロパティは、あいまいさを排除するように特別に設計されています。その一環として、に対するドット構文の使用を許可しないidという決定が下されました。

具体的には、次の状況に対処します。

@interface Foo
- (short) length;
@end

@interface Bar
- (unsigned long long) length;
@end

上記を 2 つの個別のヘッダー ファイルに指定すると、 をコンパイルすると、両方のヘッダー ファイルがインポートされている[anObject length]という警告のみが表示されます。ヘッダー ファイルが 1 つしかインポートされていない場合は、呼び出しサイトがコンパイルされ、ヘッダーにある型が返されます。呼び出しサイトが他のメソッドの場合、非常に予期しない結果が返されます。

ドット構文の制限により、この潜在的なあいまいさが解消されます。これは、メソッドの共変宣言が通常見られない理由でもあります。C ABI はそれをきれいにサポートしていません (そうは言っても、Objective-C はオブジェクト型の共分散をサポートするのに不十分な仕事をしています)。

実際には、Objective-C 開発者がこのid型を使用することはめったにありません。特定の型宣言により、コンパイラはコードの検証を大幅に改善できます。

于 2009-11-08T17:16:52.347 に答える
0

Objective-Cは動的バインディングをサポートしています。ただし、タイプ'id'のオブジェクトのプロパティを使用することはできませんが、必要なメッセージを送信することはできます。(これはおそらく現在の定義/実装の間違いです...しかし、今はそれを脇に置いておきましょう。)

あなたがした場合

NSLog(@"%@ : %@", [exc name], [exc reason] ); 

その後、それは動作します。とにかくすべて別々の行にあるため、NSLogステートメントに改行を入れる必要はないことに注意してください。

于 2009-11-08T17:08:09.943 に答える