2010-07-11 42 views
12

我知道有几个规则的有关Objective-C的类别:如果两个ObjC类别重写相同的方法会发生什么?

  1. 分类方法不应重写现有的方法(类或实例)
  2. 两个不同类别的执行同样的方法相同类将导致不确定的行为

我想知道,当我重写的叔我自己的分类方法之一,会发生什么他是同一类别。例如:

@interface NSView (MyExtensions) 
- (void)foo; // NSView category implementation 
@end 

@interface MyClass : NSView 
{ } 
@end 

@interface MyClass (MyExtensions) 
- (void)foo; // MyClass category implementation 
@end 

定义了这些接口,当我运行下面的代码时将执行哪个方法?

MyClass * instance = [[MyClass alloc] initWith...]; 
[instance foo]; 
[instance release]; 

注意:对于我的编译器,MyClass的执行优先,但我不知道这是保证发生,或者不确定的行为只是一个特定的味道。

回答

12

每个类的每个方法都有一个实现。类别为特定类添加或替换方法。这意味着你看到的行为,其中MyClass有一个foo,而NSView有另一个foo,这是很好的定义。 MyClass的任何实例与不是MyClass的NSView的任何实例都有不同的foo,就好像foo已在主实现中定义,而不是类别。您甚至应该能够从MyClass调用[super foo]访问为NSView定义的foo

+3

在超类Category中声明和实现的Category方法中覆盖是否正确? – BergP 2013-03-19 14:08:00

32

延长提前回答:

这是等级问题。类别实际上只是组织源文件的一种手段。编译时,类的所有方法(包括在任何类别中定义的方法)都会在同一个文件中结束。

您可以在常规课程界面中做任何事情,您可以在类别中进行任​​何操作,而您在课堂上不应该做的任何操作

所以:

分类方法不应重写 现有的方法(类或实例)

您可以使用常规的类接口定义覆盖方法继承方法,这样你就可以覆盖类别中的继承方法。

但是,您永远不会尝试在同一个普通接口中必须使用两个相同的方法定义,所以您不应该在类别中具有与普通接口中的方法同名的方法或同班。由于所有的方法定义都以相同的编译文件结束,它们显然会发生冲突。

两个不同类别的执行 不确定的 行为同样的方法结果

这应该被改写说“两种不同类别的执行同样的方法同一类结果不确定行为。”同样,因为任何一个类的所有方法最终都在同一个文件中,所以在同一个类中使用两个方法显然会造成怪异。

您可以使用类别提供重写超类方法的方法,因为类及其超类是两个不同的类。

如果您对某个类别是否会导致问题感到困惑,可以问问自己:“如果我将这些类别中的方法复制并粘贴到类中,.h/.m文件是否可以工作?如果答案是“是”,那么你就清楚了。如果“不”,那么你有问题。

+2

+1谢谢。这是描述它的一种非常好的方式。我也改变了规则#2的措辞以符合你的要求。 – 2010-07-11 18:09:45

相关问题