Reputation: 36143
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>
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 is bad in that it won't help anyone else who wants to call the method.
Upvotes: 5
Views: 2089
Reputation: 243156
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).
Upvotes: 2
Reputation: 28688
Just do [(MyClass*)[self class] port]
. This will work in all cases and is the simplest way.
Upvotes: 0
Reputation: 4433
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.
Upvotes: 4