2

一部のサンプルコードでは、NSNumberが可変配列に追加されています。

// In the .h, as an instance variable:
NSMutableArray *sequence;

// In the .m file:
sequence = [[NSMutableArray alloc] initWithCapacity:100];

[sequence addObject:[NSNumber numberWithInt:123]];

その後、整数が必要になると、次のものが使用されます。

[(NSNumber *)[sequence objectAtIndex:aCounter] intValue]

なぜキャスト(NSNumber *)が必要なのかしら?プログラムはそれがなくても正常に実行されるためです。それはただの良い習慣ですか?もしそうなら、それは何が起こるのを防ぐことができますか?1つの要素がではないバグがある場合NSNumber *、それをキャストすると奇妙な動作も発生する可能性があります。

4

5 に答える 5

1

// Objective-Cでは、どのオブジェクトも他のオブジェクトにメッセージを送信できます。//ここで両方の統計は完全に有効ですが

[(NSNumber *)[シーケンスobjectAtIndex:aCounter] removeFromSuperview]; //これは警告をスローし、removeFromSuperviewが呼び出されないことを通知します

[[sequence objectAtIndex:aCounter]removeFromSuperview];//ここでは警告は表示されません

于 2012-04-30T06:58:06.107 に答える
1

キャストは、オブジェクト ( type として返されるid、つまり、他の情報を持たない汎用オブジェクト型!) が実際にはNSNumberであるとコンパイラに認識させるだけで、そのintValueetc. メソッドを正確に識別できます。実行時に違いが生じることはありません。オブジェクトが NSNumber でない場合、キャストの有無にかかわらず、実行時にクラッシュします。

于 2012-04-30T06:49:14.053 に答える
1

キャストなしでそれを行うことは問題ありません。キャストは、それを NSNumber として扱うことを明示するだけです。バグがあり、これが ではないNSNumber(より正確には、 に応答しないintValue) 場合は、いくつかを取得します。とにかく挙動がおかしい。

于 2012-04-30T06:49:36.943 に答える
1

なぜキャスト (NSNumber *) が必要なのだろうか?

実行時に実際に呼び出されるセレクターの署名が翻訳に表示され、翻訳に表示されるすべてのセレクター シグネチャーが呼び出されたセレクターに一致する場合は必要ありません。

あなたはおそらく「なに?それは複雑だ!特に私のプログラムが進化するにつれて、エラーが発生しやすくなる!」と考えているでしょう。

同じセレクターの複数のセレクター シグネチャが表示され、メッセージを送信するid場合、objc コレクションが型指定されておらず、コンパイラーが正しいセレクターと一致しない可能性があるため、未定義の動作が予想されます (警告レベルが高く、インクルードがすべて正しい場合、これに関する警告が表示されます)。

これを回避する簡単な方法は、割り当てによって正しい型を再導入することです。

NSNumber * n = [array objectAtIndex:i];
int a = [n intValue];

またはキャストすることによって:

int a = [(NSNumber*)[array objectAtIndex:i] intValue];

そのため、コンパイラは型に応じてセレクターを適切に照合できます。また、オブジェクトが特定のセレクターに応答しない可能性がある場合、パラメーターまたは戻り値の型が一致しない場合、またはキャスト先の型のインターフェイスが翻訳には表示されません -- 結局のところ、コレクションに何が含まれているかを把握しておく必要があります。

その型安全性を適切に導入することは、非常に良い習慣です。

于 2012-04-30T07:31:57.093 に答える
0

キャストは、コンパイラが自分が何をしているのかわからないと文句を言うのを防ぐために必要です。

コンパイラがコンパイル時に行うことの1つは、メッセージの受信者のインターフェイスが、送信しているメッセージ(intValueこの場合)に応答すると言っているかどうかを確認することです。のインターフェースNSNumberは確かにに応答すると言っていますintValueが、の戻り型objectAtIndex:id、ジェネリックポインターです。コンパイラには、そのポインタのもう一方の端にあるオブジェクトのタイプが何であるかを知る方法がありません。これは、実行時までわかりません。

キャストはコンパイラに、あなたが実際に型を知っていること、そしてメッセージの受信者が応答するかどうかわからないという事実について警告する必要がないこと(または、場合によってはARCではエラーを出すこと)を伝えます。

キャストのクラスを応答しないものintValue(などNSDate)に変更した場合、コンパイラはあなたに不満を抱きます、オブジェクトが実際にまだだった場合NSNumber、メッセージは実行時に成功します。キャストはオブジェクトのタイプを変更できません。これは単にコンパイラの注釈です。*


*場合によっては、コードの可読性も向上する可能性があります。

于 2012-04-30T06:51:19.450 に答える