Переопределяющие методы в Objective-C - PullRequest
3 голосов
/ 30 июля 2011

Я относительно новичок в Objective-C, и я думал о том, что все методы, по сути, являются виртуальными.Я создал эту небольшую консольную программу:

#import <Foundation/Foundation.h>

@interface BaseClass : NSObject
{
}
- (void) virtualMethod: (NSInteger) integer;
@end

@interface DerivedClass : BaseClass
{
}
- (void) virtualMethod: (NSString *) string;
@end

@implementation BaseClass

- (void) virtualMethod: (NSInteger) integer
{
    NSLog(@"%ld", integer);
}
@end

@implementation DerivedClass

- (void) virtualMethod: (NSString *)string
{
    NSLog(@"%@", string); // Program received signal: "EXC_BAD_ACCESS". -- as expected
}
@end

int main (int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSArray *arr = [NSArray arrayWithObjects: [BaseClass new], [DerivedClass new], nil];
    for (int i = 0; i < arr.count; i++) 
    {
        BaseClass *b = (BaseClass *)[arr objectAtIndex: i];
        [b virtualMethod: i];
    }
    NSLog(@"\n\nTapos na!\n\n");

    [pool drain];
    return 0;
}

Как и ожидалось, я получил EXC_BAD_ACCESS в производном virtualMethod:, поскольку, в конце концов, он не принимает целое число, он принимает NSString *в качестве параметра.Виртуальный механизм основан на селекторах и, похоже, не учитывает подписи.

Мой вопрос: есть ли в языке что-то, что могло бы предотвратить такое переопределение с другой сигнатурой?Какой-то способ сказать компилятору, что virtualMethod: всегда должен иметь одну и ту же сигнатуру, или заставить компилятор выдавать какую-то подсказку, предупреждение или ошибку, если сигнатура не совпадает?

Я знаю, что это хорошопрограммист всегда указывает имена типов, которые должен иметь метод, но это соглашение, а не правило языка.Я спрашиваю о функции компилятора, чтобы предотвратить возникновение проблемы.

Ответы [ 2 ]

7 голосов
/ 30 июля 2011

Ну, есть ... но вы, вероятно, не хотите его использовать. В XCode есть параметр сборки, называемый «Strict Selector Matching» (который передается компилятору как -Wstrict-selector-match). Это предупредит вас, если компилятор найдет два селектора, которые имеют разные параметры или возвращаемые типы.

К сожалению, предупреждение появляется, даже если типы разные, но совместимые. Таким образом, если вы включите его, вы получите кучу ложных предупреждений о местах, которые вы не ожидали бы быть двусмысленными. Не стесняйтесь попробовать, однако.

Если вы хотите больше узнать об этом, Мэтт Галлахер написал хороший пост об этом . Между тем, я боюсь, что здесь нет хорошего решения.

0 голосов
/ 25 октября 2012

Текущая версия XCode выдает следующее предупреждение:

"Конфликтующие типы параметров в реализации '[method]': '[необходимый тип]' vs '[тип, который вы ошибочно выбрали]'«

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