РЕДАКТИРОВАТЬ: Проблема решена!После очистки и перезагрузки он просто исчез!Я не знаю, что вызвало это!
Это вызвало у меня головную боль на целый день:
В Xcode 3.2 все работало отлично.Затем я переключился на 4.2, и внезапно наследование классов больше не работает.
У меня есть класс TheSuperclass
и TheSubclass : TheSuperclass
.Чтобы упростить тестирование, я действительно создал их вот так.Там нет больше кода, чем вы можете увидеть здесь:
// TheSuperclass.h
@interface TheSuperclass : NSObject {
}
// subclasses must override this method
- (id)returnSomethingUseful;
@end
// TheSuperclass.m
#import "TheSuperclass.h"
@implementation TheSuperclass
- (id)returnSomethingUseful {
NSLog(@"Dude, you have to override -returnSomethingUseful");
return nil; // subclasses override this method!
}
- (id)init {
if ((self = [super init])) {
obj = [self returnSomethingUseful]; // TEST
NSLog(@"TheSuperclass initialized: %@", obj);
}
return self;
}
@end
// TheSubclass.h
#import "TheSuperclass.h"
@interface TheSubclass : TheSuperclass {
}
@end
// TheSubclass.h
#import "TheSubclass.h"
- (id)returnSomethingUseful {
NSLog(@"Correct method called!");
return usefulObject;
}
TheSubclass *foo = [[TheSubclass alloc] init]; // remember: init of superclass calls the method
// Getting the NSLog: "Dude, you have to override -returnSomethingUseful"
id bar = [foo returnSomethingUseful]; // now call it directly on foo
// Getting the NSLog: "Correct method called!"
TheSuperclass
объявляет метод шаблона, то есть метод, который ничего не делает, возвращает nil и предназначен для подклассов:
- (id)returnSomethingUseful {
NSLog(@"Dude, you have to override -returnSomethingUseful");
return nil; // subclasses override this method!
}
В TheSubclass
я просто переопределяю этот метод шаблона.И, конечно, я скопировал реализацию из TheSuperclass
, чтобы сделать ее на 100% правильной.Нет опечатка.Это проверенный факт.Выглядит так:
- (id)returnSomethingUseful {
NSLog(@"Correct method called!");
return usefulObject;
}
В реализации TheSuperclass
фрагмент кода вызывает [self returnSomethingUseful]
, чтобы получить этот объект из метода шаблона.Это отличный шаблон, и я много его использовал.Он всегда работал именно так.
Но теперь кажется, что, хотя я создаю экземпляр TheSubclass
, он всегда вызывает метод НЕПРАВИЛЬНО.Тот из TheSuperclass, вместо того, который он должен (который, конечно, является методом переопределения)
Я проверял это по крайней мере 100 раз!Серьезно, это экземпляр TheSubclass
.Он вызывает метод init TheSuperclass
, давая мне NSLogs.
Теперь действительно странная часть: когда я вызываю этот метод для моего объекта TheSubclass "извне", он работает:
TheSubclass *foo = [[TheSubclass alloc] init];
id bar = [foo returnSomethingUseful];
// Getting the NSLog: "Correct method called!"
Чтобы подчеркнуть это: когда я вызываю [self returnSomethingUseful]
изнутри реализации TheSuperclass, он вызывает реализацию WRONG (которая является суперклассом, а не перезаписанной в подклассе.
Так какя могу обойти это? Откуда это возможно? Это проблема во время выполнения, возможно, вызванная ошибкой в компиляторе?