为什么这个类别有效?类别与类扩展

时间:2012-09-20 18:38:51

标签: objective-c categories class-extensions

这就是我的一个类的实现文件中的内容......

代码设置#1

@interface MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod;
@end

@implementation MyViewController
- (void)viewDidLoad
{
    NSString *myString = [self myPrivateMethod];
    NSLog(@"%@", myString);
}

- (NSString *)myPrivateMethod
{
    return @"someString";
}
@end

使用此代码,一切正常,并记录“someString”。

但我的代码不应该以某种方式看起来不同吗?我实际上是偶然使用那个类别(我复制/粘贴了一些东西而没有注意到“PrivateMethods”就在那里;我打算使用类扩展)。

我的代码不应该看起来像下列之一:

代码设置#2

@interface MyViewController ()
- (NSString *)myPrivateMethod;
@end

@implementation MyViewController
....

或者:

代码设置#3

@interface MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod;
@end

@implementation MyViewController (PrivateMethods)
....

在这种情况下发生的事情背后有什么细微差别?代码设置#1与代码设置#2有什么不同?

编辑:有关设置#3的问题

这样做的设置是什么?这甚至会“奏效”吗?

@interface MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod;
@end

@implementation MyViewController
- (void)viewDidLoad
{
    NSString *myString = [self myPrivateMethod];
    NSLog(@"%@", myString);
}
@end

@implementation MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod
{
    return @"someString";
}
@end

1 个答案:

答案 0 :(得分:2)

选择器只是在运行时被推入同一个平面命名空间。编译器不添加额外的代码来区分选择器是一个类别中定义的方法(当发送消息时) - 它是完全平坦的。

类别符号的导出方式不同,但加载后对运行时来说并不重要。

通常应使用Setup#3:如果在类别中声明了方法,则应在类别@implementation中定义。编译器会偶尔保存你,它是一个更纯粹的结构。 (当然,并非每种方法都属于一个类别)。同样,@interface中的声明应在相应的@implementation中定义,并且类继续(@interface MONClass ())中的声明定义也应出现在主@implementation中:

@implementation MONClass
// add your @interface MONClass definitions here
// also add your @interface MONClass () definitions here
@end

更新问题

是的,这样可以。您需要做的只是#import包含@interface MyViewController (PrivateMethods)的标题。实际上我在某些课程中这样做是为了按主题进行分类/组织。

通常,“私有方法”在类继续中声明,但没有必要这样做(ivars / properties OTOH ...)。