我如何强制编译器从一组类方法共享相同的名称中选择所需的方法?
/* 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]
。