两个类方法,相同名称,不同签名:如何强制编译器使用预期的一个?

时间:2011-04-11 16:07:21

标签: objective-c gcc

如何强制编译器从一组共享相同名称的方法中选择所需的方法?

/* Use +[MyClass port](UInt16 (*)(id, SEL),
 * not +[NSPort port](NSPort *(*)(id, SEL)). */
UInt16 port = [[self class] port];

我有一个带有类方法的Objective-C类:

+ (UInt16)port;

NSPort有一个便利构造函数,其签名与此冲突:

+ (NSPort *)port;

向我的班级发送+port会产生编译器警告:

UInt16 port = [[self class] port];
    W: Multiple methods named '+port' found
    W: Using '+(NSPort *)port'
    W: Also found '+(UInt16)port'

失败:编译器选择了错误的方法签名。

类型推断失败:使用[[(MyClass *)self class] port]并不会使用正确的方法来使用它。

ETA: 以下是我现在使用的解决方法:

#import <objc/runtime.h>

Class c = [self class];
SEL s = @selector(port);
typedef UInt16 (*PortIMP)(id, SEL);
PortIMP MyClassGetPort = (PortIMP)class_getMethodImplementation(c, s);
UInt16 port = MyClassGetPort(c, s);

这很好:

  • 它正确处理任何子类实现的调度。
  • 它仅限于实施文件,因此除了实施者之外,不会对任何人造成这种丑陋。

它不好帮助任何想要调用该方法的人。

3 个答案:

答案 0 :(得分:3)

有趣......这个似乎没有明显的解决方案。

您可以使用协议来声明所需的方法,例如

@protocol MyClassProtocol
@optional 
- (UInt16)port;
@end

然后做

UInt16 port = [(id <MyClassProtocol>)[self class] port];

不漂亮,但确实有效。

答案 1 :(得分:2)

为什么不重命名方法? (跛脚,我知道)你可以争辩说一个名为“port”的方法应该返回一个端口对象(这是NSPort所做的),如果你想返回一个原始的“端口号”,那么你d称之为“portValue”(la“intValue”,“longLongValue”等)。

答案 2 :(得分:0)

[(MyClass*)[self class] port]。这将适用于所有情况,并且是最简单的方法。