将默认返回的ID更改为NSTimeInterval

时间:2014-07-10 14:34:18

标签: objective-c nstimeinterval

我有一些代码调用一个对象的方法,该对象的.h文件我没有包含在我的项目中,并且不能包含(我不想进入这个)。

但是,我知道我需要调用它具有的特定函数,它返回NSTimeInterval

显然,编译器警告我该方法未定义并可能崩溃。问题是编译器将未知函数的返回值默认为id,并且我无法将id转换为非指针值。但是,在运行时,id的值是我需要NSTimeInterval包含的值。

id tempValue = [myObject unknownNumberMethod]; // compiler says: "instance method -unknownNumberMethod not found(return type defaults to 'id'
NSTimeInterval realValue = (NSTimeInterval)tempValue; //this yields a compilation error:/Users/Niv/Projects/Copia/Copia.MAC/RMSDKServicer/RMSDKServicer/Downloader/ActivatorService.m:75:24: Initializing 'NSTimeInterval' (aka 'double') with an expression of incompatible type 'id'

我尝试声明这样的方法,只是为了让编译器理解它返回NSTimeInterval而不是id

@interface MyClass //type of myObject
-(NSTimeInterval)unknownNumberMethod;
@end

然而,这会使unknownNumberMethod不断返回0,所以我认为它会用空白方法覆盖真实方法。

我还想找到一种方法来定义一个类的extern方法,但是找不到合适的语法。

"强制"正确的方法是什么?编译器意识到即使它没有找到方法定义,它也会返回NSTimeInterval而不是id

4 个答案:

答案 0 :(得分:0)

你试过这个吗?

SEL selector = NSSelectorFromString(@"unknownNumberMethod");
if ([someInstance respondsToSelector:selector]) {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                            [[myObject class] instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:myObject];
    [invocation invoke];
    NSTimeInterval realValue;
    [invocation getReturnValue:&realValue];
}

答案 1 :(得分:0)

使用NSInvocation对象而不是performSelector调用。见NSInvocation documentation

答案 2 :(得分:0)

重述我的评论,也许这是一个坏主意,但可能有用的一件事是使用字符串格式化操作%p将id呈现为十六进制NSString,然后将其解释为双...

id tempValue = [myObject unknownNumberMethod]; // compiler says: "instance method -unknownNumberMethod not found(return type defaults to 'id'
NSString *yuck = [NSString stringWithFormat:@"%p", tempValue];

NSTimeInterval result;
NSScanner *scanner = [NSScanner scannerWithString:yuck];
[scanner scanHexDouble:&result];

答案 3 :(得分:0)

如果您无法访问头文件,那么正确的做法是在非正式协议中提供您自己的方法声明:

@interface NSObject(MyAppExtension)
- (NSTimeInterval)unknownNumberMethod;
@end

然后,您可以像调用任何其他方法一样调用该方法:

id foo = ... 

NSTimeInterval timeInterval = 0.0;
if ([foo respondsToSelector:@selector(unknownNumberMethod)]) {
    timeInterval = [foo unknownNumberMethod];
    NSLog(@"Got Time Interval: %f", timeInterval);
}
  

这使得unknownNumberMethod不断返回0,所以我认为它会用空白方法覆盖真实方法。

这是不正确的;什么都没有被覆盖。对象提供给定选择器的实现,或者它没有。

如果它没有返回您期望的值,则声明该方法的返回类型不正确。尝试将方法声明的返回类型更改为floatvoid*。返回void*的方法与在32位和64位系统上返回id的方法具有相同的调用约定。

(如果您正在为32位iOS进行编译,那么可以解释为什么id有效,而NSTimeInterval没有。请将返回类型声明为float。)< / p>