下面的代码实现了nsproxy子类,该子类将方法转发到nsnumber实例。
但是当调用[nsproxy floatvalue]时,在gcc 4.2下得到0.0。
在llvm clang下,我得到了正确的答案42.0。
知道怎么回事吗?
(顺便说一下,这是在垃圾收集下运行的)

-(id) init;
{
    _result = [NSNumber numberWithFloat:42.0];
    return self;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    return [[_result class] instanceMethodSignatureForSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    [anInvocation setTarget:_result];
    [anInvocation invoke];
    return;
}

最佳答案

代理类没有声明-floatValue的消息签名。因为它返回一个浮点数,所以这可能是一个问题。因为您没有在任何地方声明它,而且可能不会将代理对象强制转换为它的“表示类”,所以编译器必须猜测方法签名。在这种情况下,gcc编译器猜测消息将返回一个id指针。
在objective-c中,根据消息的签名和机器的结构,使用不同的函数来处理消息及其返回值。在x86机器上,返回浮点值的消息通过objc_msgSend_fpret调用,而返回voidid的函数使用objc_msgSend
由于gcc编译器假设返回值是一个id,所以它使用了后一个函数并错误地处理了结果。当当能处理好这件事很有意思,但我会犹豫是否依赖这种行为。最好在代理服务器上声明要转发的任何方法的类别。这还有一个好处,那就是删除为调用floatValue方法的代码行生成的警告。

@interface Foo (ProxyMethods)
- (float)floatValue;
@end

09-08 01:48