e.J*_*mes 13 methods inheritance cocoa objective-c categories
我知道有关Objective-C类别的一些规则:
- 类别方法不应覆盖现有方法(类或实例)
- 对同一个类实现相同方法的两个不同类别将导致未定义的行为
我想知道当我覆盖同一类别中我自己的一个类别方法时会发生什么.例如:
@interface NSView (MyExtensions)
- (void)foo; // NSView category implementation
@end
@interface MyClass : NSView
{ }
@end
@interface MyClass (MyExtensions)
- (void)foo; // MyClass category implementation
@end
Run Code Online (Sandbox Code Playgroud)
定义了这些接口后,当我运行以下代码时将执行哪个方法?
MyClass * instance = [[MyClass alloc] initWith...];
[instance foo];
[instance release];
Run Code Online (Sandbox Code Playgroud)
注意:使用我的编译器,MyClass实现优先,但我不确定是否可以保证发生,或者只是一种特定的未定义行为.
Tec*_*Zen 34
延伸到绘制的答案:
这是等级问题.类别实际上只是组织源文件的一种方式.编译时,类的所有方法(包括在任何类别中定义的方法)最终都在同一个文件中.
您可以在常规类界面中执行的任何操作,您可以在类别中执行任何您不应该在常规类界面中执行的任何操作,而不应该在类别中执行.
所以:
类别方法不应覆盖现有方法(类或实例)
您可以使用常规类接口中定义的方法来覆盖继承的方法,以便可以覆盖类别中的继承方法.
但是,您永远不会尝试在同一普通接口中使用两个相同的方法定义,因此您不应该在类别中具有与普通接口中的方法同名的方法或同一类中的另一个类别中的方法.由于所有方法定义最终都在同一个编译文件中,因此它们显然会发生冲突.
实现相同方法的两个不同类别导致未定义的行为
这应该被重写为" 为同一个类实现相同方法的两个不同类别导致未定义的行为." 同样,因为任何一个类的所有方法都在同一个文件中,所以在同一个类中有两个方法显然会引起奇怪.
您可以使用类别来提供覆盖超类方法的方法,因为类及其超类是两个不同的类.
如果你曾经对类别是否会引起问题感到困惑,那就问问自己:"如果我将这些方法复制并粘贴到类'.h/.m文件中,那么类别中的方法是否有用?" 如果答案是"是"那么你就明白了.如果"不",那么你就遇到了问题.
dra*_*ard 12
每个类的每个方法都有一个实现.类别为特定类添加或替换方法.这意味着你所看到的行为,MyClass有一个foo
,NSView有另一个foo
,很明确.MyClass的任何情况下都会有不同foo
比的NSView的任何实例,它是不是一个MyClass的,就好像foo
已经在主要执行被定义,而不是一个类别.您甚至可以[super foo]
从MyClass 调用来访问foo
NSView 的定义.