2009-07-22 3 views
1

最近私のコードで予期しないコンパイルエラーが発生したのは非常に困惑していました。私はいくつかのトラブルシューティングをした、と私は、テストコードのこのビットを思い付いた:performSelectorの結果:標準のドット表記の呼び出しと異なりますか?

1 float performSelectorResult, messageResult; 
2 SEL selector = @selector(smallContentCellMargin); 
3 
4 NSLog (@"selector %s result %f", selector, [defaults performSelector:selector]); 
5 NSLog (@"message result is %f", defaults.smallContentCellMargin); 
6 
7 performSelectorResult = [defaults performSelector:selector]; 
8 messageResult = defaults.smallContentCellMargin; 

を、私は7行目でコンパイルエラーを取得しているとして、私は、コードを実行した場合:「互換性のないタイプの割り当てに」。しかし、7行目をコメントアウトすると、コードがビルドされて実行されます。 NSLogの結果は次のとおりです。

2009-07-21 18:31:44.823 ICE[24347:20b] selector smallContentCellMargin result 0.000000 
2009-07-21 18:31:44.830 ICE[24347:20b] message result is 7.000000 

私は非常に似たコードを使ってUIFontを取得しましたが、浮動小数点は使用しませんでした。私が知らないものがありますか?これはObjective-Cのバグですか?私は非常に混乱しています。

答えて

3

まず、NSLogでロギングするときにセレクタを文字列として扱います。しないでください - SELは文字列ではありません。 %@形式とNSStringFromSelector(aSelector)を使用します。

問題のために、-performSelector:は、オブジェクトの戻り値の型を持つセレクタで動作するように定義されています。 ABIのおかげで、これはポインタのサイズまでのint型の戻り値の型(実行時の実装の詳細に依存します)で使用することができますが、気づいたように、通常は浮動小数点の戻り値を得ることはできません。

オブジェクト以外の戻り値の場合は、NSInvocationまたは-valueForKey:を使用する必要があります。後者の場合、NSNumberとして浮動小数点数を取得します。

+0

私は、-valueForKeyのクイックテストを試みました: 'float quickTest = [defaults valueForKey:@ "smallContentCellMargin"];'コードをコンパイルしようとすると、「初期化で互換性のない型」エラーが発生します。私はドキュメント内の-valueForKeyを見て、型(id)を返すと言っています - 私は何か間違ったことをしたのですか、この場合は-performSelectorと同じですか? – JoBu1324

+2

+1これは、メッセージが実際にどのように受け継がれるかについてもっと学ぶ良い機会です。メッセージは、objc_msgSend()で渡されるとよく​​言われていますが、それは単純化されています。 docs内でobjc_msgSend()を探し、それをその友人、具体的にはobjc_msgSend_fpret()と比較してください。 OPコード*はPPCで動作しますが、インテルでは動作しません。そしてそれはあなたが頼りにしたくないプラットフォーム依存性のようなものです。 Jimのアプローチを使用してください。インテルでは、インテルでもそれを乗り越えることができます。 –

+0

-valueForKeyに関するJimのコメントを再読み込みします.NSNumberを返します。 NSNumberは、数値(この場合はdouble)を表すオブジェクトです。 –

関連する問題