PerformSelectorの戻り値は何ですか。NSDateComponentsの 'week'(intを返す)など、(オブジェクトの)プリミティブ型を返すセレクターを渡した場合はどうなりますか?
NSInvocationを使用して浮動小数点数を返す例:
SEL selector = NSSelectorFromString(@"someSelector");
if ([someInstance respondsToSelector:selector]) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
[[someInstance class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:someInstance];
[invocation invoke];
float returnValue;
[invocation getReturnValue:&returnValue];
NSLog(@"Returned %f", returnValue);
}
私は、performSelectorから戻り値を取得できないと思います。 NSInvocation
を調べてください。
昔の質問に対する新しい答え〜
performSelector
から戻り値を取得するより簡潔な方法があります
NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(height) object:nil];
[invo start];
CGFloat f = 0;
[invo.result getValue:&f];
NSLog(@"operation: %@", @(f));
その中で
- (CGFloat)height {
return 42;
}
出力
2017-03-28 16:22:22.378 redpacket[46656:7361082] operation: 42
質問の2番目の部分に答えるために、プリミティブを返すセレクターを呼び出す別の方法は、次のように関数ポインターを取得して呼び出すことです(someSelectorは浮動小数点数を返し、引数がないと仮定します)。
SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));
Dizyの提案どおりに実装されたNSInvocationを試しましたが、期待どおりに機能しました。
私はまた別の方法、つまり.
int result = objc_msgSend([someArray objectAtIndex:0], @selector(currentPoint));
上記の場合、ブログに記載されているように、コンパイラーをバイパスしてobjc_msgSend呼び出しを明示的に挿入しています。 http://www.cocoawithlove.com/2011/06/big-weakness-of-objective-c-weak -typing.html
この場合、次の警告が表示されました:ライブラリ関数 'objc_msgSend'をタイプ 'id(id、SEL、...)'で暗黙的に宣言していますライブラリ関数を直接呼び出しているため、明らかです。
だから、私はNSInvocationを使って実装しましたが、これは完全にうまく機能しています。