5

オブジェクトに対して任意のセレクターを実行するにはどうすればよいですか?その戻り値はdoubleです。たとえば、メソッド-(double)blahを持つobjAがあります。

どうすればよいdouble res = [obj performSelector:@selector(blah)];ですか?PerformSelectorはタイプオブジェクトを返すidので、idからNSInteger、doubleにキャストする必要があります-精度が低下しますか?

また、実行時にCPUを大量に消費するため、obj (つまり、noおよびno )は使用しません。methodSignatureForSelectorNSMethodSignatureNSInvocation

4

3 に答える 3

8

特に、Objective-Cランタイム関数を確認することをお勧めしますobjc_msgSend_fpret

double objc_msgSend_fpret( id self, SEL op, ... )

これは、浮動小数点の戻り値を持つメッセージをクラスのインスタンスに送信します。

performSelectorメソッドは、型を返すを使用しobjc_msgSendますid

例えば:

double res = objc_msgSend_fpret( obj, @selector( blah ) );

このobjcランタイムヘッダーをインポートする必要があります。

#import <objc/message.h>

編集

ちなみに、ObjCランタイムリファレンスへのリンクは次のとおりです:http: //developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html

編集2-重要

objc_msgSend_fpretCPUアーキテクチャ(基本的にはi386またはx86_64)に応じて、さまざまな方法で実装されます。

コメントで述べたように、これらの関数はアセンブリを使用して実装されるため、実装はCPUアーキテクチャに依存します。

x86_64アーキテクチャでは、この関数はを返しますlong double

これが、に割り当てるときに失敗する(そしてNANを返す)理由ですdouble

また、objc_msgSend_fp2ret関数があることに注意してください。

したがって、基本的に、前の例は機能しません。

double x = objc_msgSend_fpret( obj, @selector( blah ) );
printf( "Val: %f\n", x );

お気づきのように、「NAN」と表示されます。

それを機能させるには、次のようにする必要があります。

long double x = objc_msgSend_fpret( obj, @selector( blah ) );
printf( "Val: %Lf\n", x );

実例は次のとおりです。

http://www.eosgarden.com/uploads/misc/fp.m

以下を使用してコンパイルします。

gcc -Wall -framework Foundation -o fp fp.m
于 2011-11-11T00:30:57.283 に答える
7

引数のないメソッドの場合は、そのメソッドから返された値にvalueForKey:andを使用できます。doubleValueそうでなければ、私はあなたがobjc_msgSend_fpretそれを機能させるためにいじくり回さなければならないと思います。

于 2011-11-11T00:30:27.050 に答える
4

使用するメモリが最も少なく(valueForKey:2つの一時オブジェクトを使用)、msgSendメソッドは機能しません。

 IMP myImp1 = [obj methodForSelector:@selector(getDouble)];
 double aDouble1 = ((double (*) (id,SEL))myImp1)(obj,@selector(getDouble));
于 2011-11-11T00:35:34.347 に答える