Objective-C继承:如何从超类调用被覆盖的方法?

6

我有一个Objective-C类,其中有一个方法是打算被重写的,它会在另一个方法中使用。代码大致如下:

@interface BaseClass
- (id)overrideMe;
- (void)doAwesomeThings;
@end

@implementation BaseClass
- (id)overrideMe {
    [self doesNotRecognizeSelector:_cmd];
    return nil;
}
- (void)doAwesomeThings {
    id stuff = [self overrideMe];
    /* do stuff */
}
@end

@interface SubClass : BaseClass
@end

@implementation SubClass
- (id)overrideMe {
    /* Actually do things */
    return <something>;
}
@end

然而,当我创建一个SubClass并尝试使用它时,它仍然在BaseClass上调用overrideMe并由于doesNotRecognizeSelector:而崩溃。(我没有做[super overrideMe]或其他愚蠢的事情)。
有没有办法让BaseClass调用被覆盖的overrideMe

2
只是为了确保我是否理解正确,您正在调用[subclassInstance overrideMe],但由于doesNotRecognizeSelector:而崩溃?听起来有点奇怪,但如果我是您,第一件事就是检查一下在覆盖方法时是否拼写了方法的名称(如果在实现中拼写方法名称错误,编译器不会抱怨,在调用正确的方法名称时,它不会被覆盖)。 - Itai Ferber
2个回答

2
您在描述的内容应该是可行的,因此您的问题可能出在其他地方,但我们没有足够的信息来帮助诊断。从您的描述中,我会说要么您正在发送消息的实例不是您认为的类,要么在声明方法名称时代码中存在一些拼写错误。在gdb下运行您的应用程序,在objc_exception_throw上添加一个符号断点,重现您的问题。一旦您的进程停在“doesNotRecognizeSelector”异常上,请打印对象描述和它的类。或者在调用-overrideMe:之前记录它:NSLog(@"object: %@ class: %@", obj, [obj class])

这是很好的建议。不过,我最终使用了一种协议,它实际上更适合这个特定的情况,但还是谢谢! - Anshu Chimala
@AnshuChimala 如果问题已经解决,请不要忘记接受答案。 - P i

-1

编写一个类别来重写BaseClass的方法。

@interface BaseClass (MyCategory)
- (id) overrideMe;
@end

@implementation BaseClass (MyCategory)
- (id) overrideMe
{
    /* Actually do things */    
    return <something>;
}

@end

现在所有的BaseClass实例将用新的实现响应选择器overrideMe

3
这是一个非常糟糕的建议:欺骗Objective C,因为你没有找到代码为什么(表面上)不能按照预期工作的原因。 - Julien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接