开发者

Two class methods, same name, different signatures: How to force compiler to use intended one?

How do I force the compiler to select the desired method from a set of class methods sharing the same name?

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

I have an Objective-C class with a class method:

+ (UInt16)port;

NSPort has a convenience constructor whose signature conflicts with this:

+ (NSPort *)port;

Sending +port to my class results in a compiler warning:

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

Fail: The compiler has chosen the wrong method signature.

Type inference fail: Using [[(MyClass *)self class] port] does not cadge it into using the right method.

ETA: Here is the workaround I am using for now:

#import <objc/runtime.h>开发者_如何学C

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

It is good in that:

  • It handles dispatching to any subclass implementation correctly.
  • It is confined to the implementation file, so this ugliness is not inflicted on anyone but the implementer.

It is bad in that it won't help anyone else who wants to call the method.


Interesting… there doesn’t seem to be an obvious solution to this one.

You could use a protocol to declare the methods you need, for instance

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

then do

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

Not pretty, but it does work.


Why not just rename the method? (lame, I know) You could argue that a method named "port" should be returning a port object (which is what NSPort does), and that if you wanted to return a primitive "port number", you'd call it "portValue" (a la "intValue", "longLongValue", etc).


Just do [(MyClass*)[self class] port]. This will work in all cases and is the simplest way.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜