4

下面的代码实现了一个 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;
} 
4

2 回答 2

6

您的代理类没有为-floatValue. 由于它返回一个浮点数,这可能是一个问题。因为您没有在任何地方声明它并且可能没有将您的代理对象转换为它的代表类,所以编译器必须猜测方法签名。在这种情况下,GCC 编译器猜测该消息将返回一个id指针。

在 Objective-C 中,根据消息的签名和机器的架构,不同的函数被用于处理消息及其返回值。objc_msgSend_fpret在 x86 机器上,通过while 函数调用返回浮点值的消息voidid使用objc_msgSend.

由于 GCC 编译器假设返回值为 anid它使用后一个函数并错误地处理结果。Clang 能够正确处理这个问题很有趣,但我会犹豫依赖这种行为。对于要转发的任何方法,最好在代理上声明一个类别。floatValue这还具有删除为调用该方法的代码行生成的警告的好处。

@interface Foo (ProxyMethods)
- (float)floatValue;
@end
于 2009-09-21T07:10:52.487 回答
-1

任何init方法都应该调用[super init];以防止意外行为。如此:

- (id)init {
    self = [super init];
    if (self) {
        // Your init code
    }
    return self;
}
于 2012-03-10T23:28:44.233 回答