Два метода класса, одно и то же имя, разные подписи: как заставить компилятор использовать один из них? - PullRequest
5 голосов
/ 11 апреля 2011

Как заставить компилятор выбрать нужный метод из набора класса методов с одинаковыми именами?

/* 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'

Fail: компилятор выбрал неверную сигнатуру метода.

Ошибка вывода типа: использование [[(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 ]

3 голосов
/ 11 апреля 2011

Интересно ... Кажется, не существует очевидного решения этого.

Вы можете использовать протокол для объявления необходимых вам методов, например,

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

, затем сделать

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

Не красиво, но работает.

2 голосов
/ 11 апреля 2011

Почему бы просто не переименовать метод? (Хм, я знаю) Вы можете утверждать, что метод с именем "port" должен возвращать объект порта (что и делает NSPort), и что если вы хотите вернуть примитивный "номер порта", вы бы это "portValue" (а-ля "intValue", "longLongValue" и т. д.).

0 голосов
/ 11 апреля 2011

Просто сделай [(MyClass*)[self class] port].Это будет работать во всех случаях и является самым простым способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...