2012-04-30 7 views
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 *)必要ですか?プログラムもそれなしでうまく動作するので。それは単なる良い練習ですか?もしそうなら、何が起こるのを防ぐことができますか?一つの要素は、NSNumber *ならないようにバグがある場合、それはあまりにも奇妙な行動を作成することができますキャスト。

答えて

1

キャストは、コンパイラが、それはそのintValueなどのメソッドをcorreclty識別できるように、オブジェクト(タイプidのとして返される、すなわちなし他の情報と汎用オブジェクト型が!)、実際にNSNumberであると信じています。実行時に異なるものにすることはありません。オブジェクトがするNSNumberではない場合、それはキャストの有無にかかわらず、実行時にクラッシュします。

1

キャスティングをしなくても問題ありません。キャスティングではバグがあり、これがNSNumberではない場合はそれをNSNumberとして扱うことが明示されています(または正確にはintValueとにかくあなたは奇妙な行動を取るでしょう。

0

キャストはちょうどそれはあなたが何をやっている知っているかわからないということ文句から、コンパイラを停止するために必要とされています。

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

キャストは、実際にその型を知っていることをコンパイラーに伝えます。キャストはコンパイラーにタイプを知っていることを通知します。メッセージが応答します。

オブジェクトが本当に、まだメッセージNSNumberた場合は(たとえばNSDateなど)intValueに応答しなかった何かにキャストのクラスを変更した場合、コンパイラはあなたに不満だろうと注意、しかし実行時には成功するでしょう。鋳物は、オブジェクトの種類を変更することはできません。コンパイラの単なる注釈です。*


*場合によっては、コードの読みやすさも向上することがあります。

+0

HM ...しかし、キャストが削除された場合、コンパイラは、(私はXcodeの4.3.2を使用しています)警告を与えるのいずれか...いない... –

+0

uは任意のオブジェクトにメッセージを渡すことができるので、それは文句を言わない与えますNSNumberに定義されていない他のメソッドをキャストしようとすると、警告がスローされます。 – Allamaprabhu

+0

@Jeremy:そうです。私は一般的なキャスティングの説明に少し夢中になりました。 –

1

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

[sequence objectAtIndex:aCounter] removeFromSuperview]; //これは警告をスローし、uはremoveFromSuperviewが呼び出されshpuld'nt知ることができます

[[シーケンスobjectAtIndex:aCounter] removeFromSuperview]; //ここでUは文句を言わない理由キャスト(

1

私はちょうど疑問に思うどんなwarnigを取得NSNumber *)が必要ですか?

それは実行時に実際に呼ばれていますセレクタの署名が翻訳に表示されている場合必要に応じて、と呼ばれていセレクタの翻訳の試合へのすべてのセレクタ署名見えていません。

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

同じセレクタの複数のセレクタの署名が表示され、あなたのメッセージid場合にObjCコレクションが入力されていないと、コンパイラは(正しいセレクタと一致しない場合があるので、あなたの警告レベルが高い場合、その後、あなたは未定義の動作を期待すべきであるがとあなたのインクルードはすべて正しいです、これについての警告を見ることができます)。

これを回避するための簡単な方法は、割り当てによって正しいタイプを再導入することである。

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

又は鋳造によって:ので、コンパイラは型に適切にセレクタを一致させることができ

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

、及びまた、オブジェクトは、指定されたセレクタに応答しないことがありますときに警告、またはパラメータまたはが戻ると型が一致しない、またはタイプのインターフェイスは、あなたがそれを翻訳に表示されていないためにキャストした場合 - 結局のところ、あなたが持っている必要がありますコレクションに含まれるもののアイデア。適切にその型の安全性を紹介

は非常に良い習慣です。

関連する問題