如何防止方法被错误地覆盖

Nav*_*han 3 methods overriding objective-c

如何防止方法在子类中被覆盖,在?中缺少对其超类的实现的调用?
我知道[super methodName];有时会打电话来解决我的问题.
但是,如果其他人要使用我的父级并超越我的方法,不小心失去了打电话给超级,我该怎么办?

更多解释:

我创建了一个viewcontroller VC1,它有一个方法-(void)indexDidChange:(int)index { }.我在那里写了一些我需要每次都要执行的操作.我将这个名为SVC1的viewcontroller子类化,我需要-(void)indexDidChange:(int)index { }做一些其他操作,但同时VC1 -(void)indexDidChange:(int)index { }动作也需要执行.所以我需要打电话,

 -(void)indexDidChange:(int)index { 
[super indexDidChange:index];
}
Run Code Online (Sandbox Code Playgroud)

所以我决定改变VC1的功能,比如

  -(void)indexDidChange:(int)index {
     [self currentIndexDidChange:(int)index];
 }

-(void)currentIndexDidChange:(int)index { }
Run Code Online (Sandbox Code Playgroud)

我需要 - (void)currentIndexDidChange:(int)index {}来覆盖和阻止 - (void)indexDidChange:(int)index {}来覆盖.

可能吗?

Reg*_*ent 8

编辑:在OP重新提出问题后,很明显OP实际上并没有寻找最终方法,尽管问题是初步措辞,这暗示了这一点.

OP关于方法覆盖安全的问题的新(更新)答案:

根据你的重新提出的问题,你不是要保护一个方法根本不被覆盖,而是担心你的一个子类覆盖一个方法而且意外地缺少在新实现中包含对super的调用.

然而,这是一个相当普遍和普遍存在的问题,而且你每天都要处理这个问题,而不必过多关注它.

每个Objective-C程序员都熟悉以下方法,对吧?

- (void)dealloc {
    [iVar release], iVar = nil;
    [super dealloc]; //skipping this call to super is fatal!
}
Run Code Online (Sandbox Code Playgroud)

我们知道跳过这些[super dealloc];让事情变得不舒服.(如果dealloc缺少对super的调用,那么clang编译器会发出警告,...非常方便.)

尽管这种方法的严重压倒可能会产生致命的后果,但Apple并没有选择在此处设置任何类型的安全系统.

相反,Apple做到了这一点(与需要调用super的任何其他方法一样):

  • 在方法的文档中添加注释:

在执行特定于类的释放后,子类方法应该通过消息将dealloc的超类版本合并到super中

  • 期待你,程序员,成为一个成年人,并对你的工作负责.并按规则进行游戏(由文档定义).

请记住,这- (void)dealloc绝不是例外.Cocoa中有几十种这种类型的方法.(- (id)init仅举几例KVO观测方法的衍生物等等,仅举几例.)

所以你应该做的是:

  1. 为您的方法写一个很好的文档.(实际上对你的整个项目更好)
  2. 在方法的文档中添加一个大声的注释,解释其规则.
  3. 为每个子类的重写方法实现添加注释,在调用行的正上方super,告诉读者/ dev在查询规则时查找文档.(可选的)
  4. 负责任地编码.否则,您不应该首先编码.最终,这是你的客户将遭受它的痛苦.

关于实现伪决赛方法的旧(预重述)答案:

您要求的是相当于最终函数,如Java或C++所知.与Java或C++不同,Objective-C 中没有最终方法.

根据您的情况,有一些解决方案可能会使您至少接近您的目标.你所能得到的只是稍微好一点的分离.您不会从中获得任何重要的安全性.在Objective-C中,您甚至无法确定方法的来源.方法调配允许您随意交换方法.使用代码注入,您甚至可以在运行时将代码注入进程.所有这些都是Objective-C的设计.Objective-C允许您锯掉您所坐的分支.因此,它要求你像成年人一样行事.因此,也没有私人方法.如果一个方法宣称私有,那么你作为开发人员应该相应地行事.

现在可能的" 解决方案 ":

如果只是你的超级类,如果应该调用给定的(最终)方法:

  1. 然后,Macmade使你的方法成为伪私有方法解决方案可以很好地工作.隐藏方法声明的缺点是,从子类调用隐藏方法会给你一个编译器警告,基本上阻止*(sic!)*你调用它.(它不会阻止你调用该方法.它只会通过抛出编译器警告来避免你这样做.)

但是,如果要求子类调用给定(最终)方法:

  1. 使用委托模式,这样只会使那些允许被覆盖的方法公开.
  2. 为了防止覆盖,你可以使用类集群抽象工厂模式,它们会隐藏你的实现类,从而完全防止覆盖.(苹果NSArray,NSDictionary,NSSet班做到这一点)

但是你可能会注意到,由于Objective-C缺乏保护,通常只能在两者之间做出选择:开放性,保护性,而不是混合它们.