如何防止方法在子类中被覆盖,错过了对其超类的实现的调用?。
我知道打电话[super methodName];
有时会解决我的问题
但是,如果其他人要使用我的父类并覆盖我的方法,不小心失去了打电话给超级,我该怎么办?
更多解释:
我创建了一个具有方法-(void)indexDidChange:(int)index { }
的viewcontroller VC1。我在那里写了一些我需要每次都要执行的操作。我将这个名为SVC1的viewcontroller子类化为其中我需要-(void)indexDidChange:(int)index { }
来执行其他操作,但同时VC1 -(void)indexDidChange:(int)index { }
操作也需要执行。所以我需要打个电话,
-(void)indexDidChange:(int)index {
[super indexDidChange:index];
}
所以我决定改变VC1的功能,如
-(void)indexDidChange:(int)index {
[self currentIndexDidChange:(int)index];
}
-(void)currentIndexDidChange:(int)index { }
我需要 - (void)currentIndexDidChange:(int)index {}来覆盖和阻止 - (void)indexDidChange:(int)index {}来覆盖。
有可能吗?
答案 0 :(得分:8)
编辑:在OP重新提出问题之后,很明显OP实际上并不是在寻找最终方法,尽管问题是初步措辞,这暗示了这一点。
根据您的重新定义的问题,您并不是要保护方法完全不被覆盖,而是担心您的某个子类会覆盖某个方法,并且意外地忽略了在其新实现中包含对super的调用。
然而,这是一个相当普遍且普遍存在的问题,而且您每天都在处理这些问题,而不会过多关注它。
每个Objective-C程序员都熟悉以下方法,对吧?
- (void)dealloc {
[iVar release], iVar = nil;
[super dealloc]; //skipping this call to super is fatal!
}
我们知道跳过[super dealloc];
会让事情变得不舒服。 (如果dealloc缺少对super的调用,那么clang编译器会发出警告,...非常方便。)
尽管这种方法的重写可能会导致致命的后果,但Apple并没有选择在此处设置任何类型的安全系统。
相反,Apple做了这个(与需要调用super的任何其他方法一样):
请记住,- (void)dealloc
绝不是例外。 Cocoa中有几十种这种类型的方法。 (以- (id)init
的任何衍生物,大多数KVO观测方法等为例,仅举几例。)
所以你应该做的是:
super
的行的正上方,告诉读者/ dev查找文档,如果有疑问的话规则。 (可选)您要求的是等同于最终函数,如Java或C ++所知。 与Java或C ++不同,Objective-C中没有最终方法。
根据您的情况,有一些解决方案可能使您至少接近您的目标。 你所能得到的只是稍微好一点的分离。您不会从中获得任何重要的安全性。在Objective-C中,您甚至无法确定方法的来源。 方法调整允许您随意交换方法。使用代码注入,您甚至可以在运行时将代码注入流程。所有这些都是Objective-C的设计。 Objective-C允许您锯掉您所坐的分支。因此,它要求你像成年人一样行事。因此,也没有私人方法。如果一个方法声称是私有的,那么你作为开发者应该有相应的行为。
现在可能“ solutions ”:
如果只有你的超级班级应该调用给定的(最终)方法:
但是,如果要求子类调用给定(最终)方法:
NSArray
,NSDictionary
,NSSet
类执行此操作)但是你可能会注意到,由于Objective-C缺乏保护,通常只能在两者之间做出选择:开放性,保护性,不混合。
答案 1 :(得分:4)
您可以在实现中使用类别,因此您的方法不会在头文件中公开。
MyClass.m
@interface MyClass( Private )
- ( void )myMethod;
@end
@implementation MyClass( Private )
- ( void )myMethod
{}
@end
@implementation MyClass
/* ... */
@end
答案 2 :(得分:0)
如果您没有在“.h文件”中声明您的功能,那么我认为它没有列出。