4

假设我有一个选择器,它可以分配给几种不同的方法——每个方法都有不同的返回值。

有没有办法在调用“performSelector”之前检查选择器所持有的方法的返回值是什么?

4

4 回答 4

9

有没有办法在调用“performSelector”之前检查选择器所持有的方法的返回值是什么?

价值?不,类型?是的。似乎您想要方法的返回类型(或者您的问题没有意义)。

Method m = class_getInstanceMethod([SomeClass class], @selector(foo:bar:));
char type[128];
method_getReturnType(m, type, sizeof(type));

然后你可以检查返回的类型字符串在type. 例如,"v"表示无效(谷歌完整列表)。

于 2013-01-30T11:37:51.450 回答
7

您可能会为此目的使用 Apple Docs 中推荐的 NSInvocation

这是一些使用 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);
}
于 2013-01-30T11:29:43.950 回答
1

如果该方法没有返回一个对象(它返回一个原始类型),那么使用 NSInvocation 代替。

@implementation NSObject(SafePerformSelector)
-(id) performSelectorSafely:(SEL)aSelector;
{
    NSParameterAssert(aSelector != NULL);
    NSParameterAssert([self respondsToSelector:aSelector]);

    NSMethodSignature* methodSig = [self methodSignatureForSelector:aSelector];
    if(methodSig == nil)
        return nil;

    const char* retType = [methodSig methodReturnType];
    if(strcmp(retType, @encode(id)) == 0 || strcmp(retType, @encode(void)) == 0){
        return [self performSelector:aSelector];
    } else {
        NSLog(@"-[%@ performSelector:@selector(%@)] shouldn't be used. The selector doesn't return an object or void", [self class], NSStringFromSelector(aSelector));
        return nil;
    }
}
@end
于 2014-03-21T13:23:25.300 回答
-1

performSelector:总是返回一个id. 返回的实际类型由您调用的方法确定;所以没有办法事先知道。

于 2013-01-30T11:33:45.803 回答