我有一些代码调用一个对象的方法,该对象的.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
?
答案 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,所以我认为它会用空白方法覆盖真实方法。
这是不正确的;什么都没有被覆盖。对象提供给定选择器的实现,或者它没有。
如果它没有返回您期望的值,则声明该方法的返回类型不正确。尝试将方法声明的返回类型更改为float
或void*
。返回void*
的方法与在32位和64位系统上返回id
的方法具有相同的调用约定。
(如果您正在为32位iOS进行编译,那么可以解释为什么id
有效,而NSTimeInterval
没有。请将返回类型声明为float
。)< / p>