我可以使用一个类别(category)来覆盖已经使用另一个类别实现的方法吗?就像这样:
1)原始方法
-(BOOL) method {
return true;
}
2) 重写方法
-(BOOL) method {
NSLog(@"error?");
return true;
}
这个行得通吗,还是说会有违法的问题?
我可以使用一个类别(category)来覆盖已经使用另一个类别实现的方法吗?就像这样:
1)原始方法
-(BOOL) method {
return true;
}
2) 重写方法
-(BOOL) method {
NSLog(@"error?");
return true;
}
这个行得通吗,还是说会有违法的问题?
根据 Apple 文档:
虽然 Objective-C 语言目前允许使用分类来重写类继承的方法,甚至是类接口中声明的方法,但强烈不建议这样做。分类不能替代子类。使用分类重写方法有几个明显的缺点:
当一个分类重写一个继承的方法时,分类中的方法可以像往常一样通过消息发送到
super
来调用继承的实现。然而,如果一个分类重写了存在于该分类所属类中的方法,则没有办法调用原始实现。一个分类无法可靠地重写同一类的另一个分类中声明的方法。
这个问题尤其重要,因为许多 Cocoa 类都是使用分类实现的。你试图重写的一个框架定义的方法可能已经在一个分类中实现,因此哪个实现会优先使用是未定义的。
某些分类方法的存在可能会导致所有框架的行为发生变化。例如,如果你在 NSObject 上的一个分类中重写
windowWillClose:
委托方法,那么程序中所有窗口委托都将使用该分类方法进行响应;所有 NSWindow 实例的行为可能会发生变化。在框架类上添加的分类可能会导致行为发生神秘的变化,并导致崩溃。
旧的文件链接已经失效,我所能找到的最佳替代品是这里:Apple Docs:
避免类别方法名称冲突
由于在类别中声明的方法添加到现有类中,因此您需要非常小心地处理方法名称。
如果在类别中声明的方法名称与原始类中的方法名称相同,或与同一类别中(甚至是超类)的另一个方法名称相同,则行为未定义,无法确定在运行时使用哪个方法实现。如果您正在使用类别与自己的类一起使用,则可能不太可能出现此问题,但是在使用类别将方法添加到标准Cocoa或Cocoa Touch类中时可能会导致问题。
这是苹果使用了更轻柔的方式,但主要观点是相同的:您会引发灾难,因为不可预测的行为是沉默的。