使用Objective-C中的类别覆盖方法

ret*_*tix 87 objective-c categories

我可以使用类类别来覆盖已使用类别实现的方法吗?像这样:

1)原始方法

-(BOOL) method {
  return true;
}
Run Code Online (Sandbox Code Playgroud)

2)覆盖方法

-(BOOL) method {
  NSLog(@"error?"); 
  return true; 
}
Run Code Online (Sandbox Code Playgroud)

这会起作用,还是非法的?

Ben*_*oît 144

来自Apple文档:

尽管Objective-C语言当前允许您使用类别来覆盖类继承的方法,甚至是类接口中声明的方法,但强烈建议您不要这样做.类别不能替代子类.使用类别覆盖方法有几个重大缺点:

  • 当类别覆盖继承的方法时,类别中的方法可以像往常一样通过消息来调用继承的实现super.但是,如果类别覆盖类别类中存在的方法,则无法调用原始实现.

  • 类别无法可靠地覆盖在同一类的另一个类别中声明的方法.

    这个问题特别重要,因为许多Cocoa类都是使用类别实现的.您尝试覆盖的框架定义方法本身可能已在类别中实现,因此未定义优先级高的实现.

  • 某些类别方法的存在可能会导致所有框架的行为更改.例如,如果windowWillClose:在NSObject上覆盖类别中的委托方法,则程序中的所有窗口委托都会使用category方法进行响应.您所有NSWindow实例的行为可能会发生变化.您在框架类上添加的类别可能会导致行为发生神秘变化并导致崩溃.

  • 链接坏了,这是新版本吗?https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html (2认同)

Mar*_*aev 18

您可以通过调整类聚类方法或使用方法调配技术来实现此目的.

否则,两个或多个分类方法的行为是不确定的


Ami*_*aiB 9

旧的文档链接已经死了; 我能找到的最佳替代品是:Apple Docs:

避免使用类别方法名称冲突

因为在类别中声明的方法被添加到现有类中,所以您需要非常小心方法名称.

如果在类别中声明的方法的名称与原始类中的方法相同,或者在同一个类(或甚至是超类)上的另一个类别中的方法相同,则关于在哪个方法实现中使用哪个方法实现的行为是未定义的.运行.如果您使用具有自己类的类别,则不太可能成为问题,但在使用类别向标准Cocoa或Cocoa Touch类添加方法时可能会导致问题.

这是苹果使用更轻松的触摸,但重点是相同的:你邀请灾难,因为不可预测的行为是沉默的.