2011-12-08 4 views
3

私は自分のプログラムに書かれた非常に悪いコードを持っています。私はObjective CとiOSプラットフォームを学んでいるので、ただ遊んでいました。私は、NSMutableArrayインスタンスへのobjectForKeyへのメッセージの送信、それは動作します!不思議ですか?

私はこのようなNSMutableArray

placeInfo = [NSMutableArray array]; 

を作成していなかったと、後に自分のコードに比べて、私はこのような何かをやっている、基本的に私はGoogleの場所APIレスポンス(JSON)を操作しています。

NSDictionary *results = [responseString JSONValue]; 
placeInfo = [results objectForKey:@"result"]; 
self.phoneNumber = (NSString *)[placeInfo objectForKey:@"formatted_phone_number"]; // In this line compiler warns me that NSMutableArray might not response to this. 

私は、ドキュメントをチェックしますが、私はNSMutableArrayにobjectForKey見つけることができませんでした。

  • だからこそ、どうしてですか?なぜ私のコードがクラッシュしていないのですか?なぜ "formatted_phone_number"キーで電話番号を返すのですか?

EDIT

最初の答えの後、私は私のコードと、このようにキャスト追加タイプを編集しているが、それはまだ動作します。

NSDictionary *results = [responseString JSONValue]; 
placeInfo = (NSMutableArray *)[results objectForKey:@"result"]; 
self.phoneNumber = (NSString *)[placeInfo objectForKey:@"formatted_phone_number"]; 
+1

placeInfoは何でも[results objectForKey:@ "result"]が返すもので、おそらくNSArrayではありません。あなたはデバッガでそれを調べましたか? –

+0

@VladimirGritsenko、ええ、それは多くの理解を助けました、ありがとう:) – doNotCheckMyBlog

+0

ここでの鍵は、Objective-Cが動作する方法です。あなたが思っているかもしれないタイプやそれにキャストしたタイプにかかわらず、それを伝えるメッセージをオブジェクトに送ります。 'NSLog(@"%@ "、placeInfo);'のような行をコードに追加すると、実行時に実際にどのような型のオブジェクトが表示されるのでしょうか? – paulbailey

答えて

3

私はGoogleプレイスAPIを使用したことがありませんが、私は[results objectForKey:@"result"]は、実際には別の辞書を返すので、objectForKey:作品推測すると思います。

objective-cはポインタを使用してオブジェクトを参照するだけなので、実際にNSMutableArrayに変換されることはありません。また、objective-cは動的な性質のためメソッドが存在するかどうかをコンパイル時に知りません(実行時にメソッドや実際にクラス全体を追加することもできます)。

コンパイラの設定によっては、それだけでobjectForKey:実行時に発見し、それがとにかくコンパイル継続させていない可能性がありますという警告が表示されることがあります。実際にはNSDictionaryを渡すとうまく動作します。

キャストを(NSMutableArray *)の前に置いても、何も変更されません。これは単純にポインタ型をキャストし、オブジェクトを実際には変更しません。

+0

鋳造に関する注釈を追加しました。これは単純にポインタをキャストし、オブジェクトがメッセージにどのように応答するかを変更しません。 – DouglasHeriot

+0

すべての型を 'id'だけに変更しても、それはおそらくまだうまく動作しています - ポインタの型はオブジェクト自体について何も変更しません。 – DouglasHeriot

+0

@all、はい、あなたは正しい...私はこれを徹底的にgrokする必要があります:) – doNotCheckMyBlog

2

[results objectForKey:@"result"]NSMutableArrayではないものを返すため、これが行われています。返されているものはです。objectForKey:にはもちろん対応しています。result = [placeInfo objectForKey:@"result"]の後にブレークポイントを設定し、resultを検査してください。デバッガは、あなたが扱っているオブジェクトの種類を教えてくれます。私はあなたが好きな何でも賭けるよそれはNSDictionaryだ。

Objective Cでは、セレクタと呼ばれるメッセージを任意のオブジェクトにいつでも送信できます。ランタイムは特定のオブジェクトが指定されたセレクタを実装しているかどうかは気にしません。ターゲットオブジェクトが指定されたセレクタに応答しない場合、それは無視されます。それはクラッシュしません。この点では、C++やJavaを含む他のほとんどのOOP言語とは全く異なります。これは、特定のクラスが実装していないメソッドを呼び出そうとするとコンパイルに失敗します。オブジェクトが特定のセレクタ(特定のクラスが特定のメソッドを実装しているかどうかを知るためにイントロスペクションを使用することに類似しています)にオブジェクトが応答するかどうかは、[result respondsToSelector:@selector(objectForKey:)]となります。 Objective Cを理解するには、メソッドとメッセージのこの違いが非常に重要です。私は何か他のことをする前にThe Objective C Programming Languageを読むことをお勧めします。

また、Objective Cの型システムは、他の言語よりもストレスなく適用されます。あなたがここでやったことをするのはかなり妥当です(それは非常に悪い考えですが)NSMutableArrayのポインタを宣言して、それを(私は推測している)NSDictionaryに割り当てます。

関連する問題