1

こんにちは、Cocoa の Objective-C で実行時の型チェックなどを実施する方法を探しています。

これは私のコードサンプルです。変数 'b' への間違った割り当てに関する実行時エラーが発生することが予想されました。しかし、そうではありませんでした。エラーなしでコンパイルおよび実行されました。

#import <Foundation/Foundation.h>

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

 NSArray* a = [NSArray arrayWithObject: @"TEST"]; 
 NSURL* b = [a objectAtIndex:0]; 

    NSLog(@"Is this URL? %i", [b isKindOfClass:NSURL.class]);
    [pool drain];
    return 0;
}

// Console log after program execution:
// 2010-01-11 10:25:02.948 Type Checking[98473:a0f] Is this URL? 0

ランタイム型チェックがないことに驚きました。VB、C#、Java、ActionScript などのすべての高水準言語を使用したため... C などの低水準言語を知らないので、これが正しい方法かどうかわかりません... 理解するのは本当に難しかったです。コンパイル エラーや実行時エラーが発生しない理由。しかし、これは実際の C の世界では当然のルールとして理解できるようになりました。しかし、より強力な型チェックは私を大いに助けてくれます。デバッグセッションだけでも。これを行う方法はありますか?

また、実行時の型チェックがない場合、間違った型の値についてどのようなコーディングおよびデバッグ戦略を使用する必要がありますか? また、実行時の型チェックを行うか行わないかのトレードオフは何ですか?

4

3 に答える 3

2

実行時の型チェックがありますが、それは少し後で行われます。NSString インスタンスを NSURL* 変数に入れようとすると、何らかの例外が発生することが予想されると思います。代わりに、NSString インスタンスで NSURL 固有のメソッドを呼び出そうとすると、例外が発生します。

たとえば、試し[b isFileURL]てみると、「NSString がセレクター 'isFileURL' に応答しません」のような例外が発生します。

例にコンパイル時の型チェックがない理由を理解することも重要です。具体的には、コンパイル時の型チェックの欠如は、型のユニークで重要なプロパティであり、idNSArray が-objectAtIndex:返すものです。

于 2010-01-11T02:01:22.603 に答える
1

Objective-C には、メッセージ引数と戻り値の型のコンパイル時の型チェックがありますが、他の多くの言語よりもやや緩いです。大きな違いの 1 つは、NSArray や NSDictiomary などのコレクション クラスがジェネリックであることです。任意の型のオブジェクトを NSArray に入れることができます - 要素は同じ型である必要はありません。したがって、要素を追加またはアクセスするときの型チェックはありません。

変数の代入に対する実行時の型チェックはありません。それがパフォーマンスのショートカットだと思います。一般的に、それはあまり問題ではありません。間違った型の値が変数に代入されると、最終的に理解できないメッセージが送信され、非常に便利なエラー メッセージが生成されます。

于 2010-01-11T02:36:07.027 に答える
0

NSObject フレームワークは、タイプが間違っていると大騒ぎすることがよくありますが、タイプを手動でチェックして例外をスローすることができます。

if (![obj isKindOfClass:SomeObjectClass.class])
  [NSException raise:@"BadTypeException"
    format:@"Bad type at line %d", (int)__LINE__];
[obj xyz];

...

if (![obj conformsToProtocol:@protocol(SomeProtocol)])
  [NSException raise:@"BadTypeException"
    format:@"Bad type at line %d", (int)__LINE__];
[obj abc];

編集:存在しないメソッドへの呼び出しがnilまたはゼロを返すと主張する前のセクションを削除しました。Mark Bessey が言うように、nil 以外のオブジェクトがメソッドを実装していない場合、例外がスローされます (0 は返されません)。

于 2010-01-11T02:26:25.347 に答える