在Objective-C中使用类别重写方法
我可以使用类别来覆盖已经使用类别实现的方法吗? 喜欢这个:
1)原始方法
-(BOOL) method { return true; }
2)重写方法
-(BOOL) method { NSLog(@"error?"); return true; }
这工作,或者这是非法的?
从Apple文档 :
虽然Objective-C语言目前允许使用类别来覆盖类inheritance的方法 , 甚至是在类接口中声明的方法,但是强烈build议您不要这样做 。 一个类别不能代替一个子类。 使用类别来覆盖方法有几个显着的缺点:
当类别重写inheritance的方法时,类别中的方法可以像往常一样通过消息调用inheritance的实现。 但是, 如果某个类别覆盖了该类别中存在的方法,则无法调用原始实现 。
类别不能可靠地覆盖在同一类的另一个类别中声明的方法。
这个问题是特别重要的,因为许多Cocoa类是使用类别实现的。 您尝试覆盖的框架定义的方法本身可能已经在类别中实现,因此没有定义哪个实现优先。
某些类别方法的存在可能会导致所有框架的行为变化。 例如,如果覆盖NSObject类别中的
windowWillClose:
delegate方法,则程序中的所有窗口委托都会使用类别方法进行响应; NSWindow的所有实例的行为可能会改变。 您添加到框架类的类别可能会导致行为的神秘变化,并导致崩溃。
你可以通过适应类的方法来做到这一点,或使用方法swizzling技术。
否则,两个或多个分类方法的行为是不确定的
旧的文档链接已经死了。 我能find的最佳替代品是在这里: Apple Docs :
避免类别方法名称冲突
由于在类别中声明的方法被添加到现有的类中,所以您需要非常小心方法名称。
如果在类别中声明的方法的名称与原始类中的方法相同,或者在同一个类(甚至是超类)上的另一个类中的方法相同,则行为是不确定的运行。 如果您使用自己的类使用类别,但这不太可能成为问题,但在使用类别向标准Cocoa或Cocoa Touch类添加方法时可能会导致问题。
这是苹果使用更轻的触摸,但重点是相同的:你邀请灾难,因为不可预知的行为是沉默的。
重要的是要注意,一个类别也可以用来覆盖基类中的现有方法(例如,Car类的驱动方法),但不应该这样做。 问题在于类别是一个扁平的组织结构。 如果您覆盖Car + Maintenance.m中的现有方法,然后决定要使用另一个类别再次更改其行为,则Objective-C无法知道要使用哪个实现。 在这种情况下,子类化几乎总是一个更好的select。