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



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

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

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

+ (UInt16)port;

NSPort有一个方便的构造函数,它的签名与this冲突:

+ (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);

它的优点在于:

  • 正确处理分派到任何子类的实现。
  • 它被限制在实现文件中,所以除了实现者之外,这种丑陋不会强加给任何人。

有趣,这个问题似乎没有一个明显的解决方案。

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

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

那么做

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

为什么不直接重命名方法呢?(蹩脚的,我知道)你可以争辩说,一个名为"端口"的方法应该返回一个端口对象(这就是NSPort所做的),如果你想返回一个原始的"端口号",你会称之为"portValue"(像"intValue","longLongValue"等)。

只做[(MyClass*)[self class] port]

最新更新