35

作为一个相当新的 Objective-c 程序员(有 4 年的 Java 经验),我似乎很难理解何时使用类扩展。据我了解(如果我错了,请纠正我),类别和扩展之间的主要区别在于,扩展希望您在主实现中实现方法,而对于一个类别,它可以在另一个实现中. 人们似乎也主要将扩展用于私有方法。

这是我的第一个问题。使用类扩展声明私有方法和根本不声明它有什么区别(在这两种情况下似乎都在运行中编译)?(示例 1 与 2)

示例 1

@interface Class()
-(void) bar;
@end

@implementation Class
-(void) foo {
    [self bar];
}

-(void) bar {
    NSLog(@"bar");
}
@end

示例 2

@implementation Class
-(void) foo {
    [self bar];
}

-(void) bar {
    NSLog(@"bar");
}
@end

第二个问题:在扩展中声明 ivars 和在实现中直接声明有什么区别?(例 3 对 4)

示例 3

@interface Class() {
    NSArray *mySortedArray;
}
@end

@implementation Class
@end

示例 4

@implementation Class
NSArray *mySortedArray;
@end

我有一个关于编码约定的最后一个问题:我什么时候应该在变量名前加上下划线 (_)?

谢谢

4

5 回答 5

28

类扩展中的方法

过去从来没有这样的情况,您不需要声明您的私有方法。直到最近,您还需要在某个地方声明私有方法,而大多数人选择了类扩展来这样做。从 Xcode 4.4(我相信)开始,编译器足够聪明,可以确定在该实现中哪些方法是私有的,无需在其他地方声明它们。

类扩展中的变量

至于示例 3 和示例 4,请小心。在类扩展中,变量是该类的实例变量(示例 3)。示例 4 声明了一个全局变量(因为它遵循 C 中的全局变量语义)。对于您的私有实例变量,请坚持使用示例 3。

编码约定

至于编码约定,由开发人员/团队决定是否使用下划线。我们的团队使用m_私有实例变量。Apple 在他们的文档中建议使用下划线(这是合成属性的基础实例变量的命名样式)。重要的是,在整个代码中保持一致。

于 2013-02-03T17:52:13.170 回答
8

类别和扩展之间的主要区别在于,扩展希望您在主实现中实现方法,而对于一个类别,它可以在另一个实现中。人们似乎也主要将扩展用于私有方法。

正确的。

使用类扩展声明私有方法和根本不声明它有什么区别(在这两种情况下似乎都在运行中编译)?

也许只是关于未声明选择器的编译器警告。(当然它运行良好 - 该方法已实现并且确实存在。)还要注意,编译器需要声明(已知的正确函数签名)才能发出符合 ABI 的正确二进制代码。它对未声明的方法(即它们返回id并接受可变参数)所做的假设可能不正确 - 通过不兼容类型的指针调用函数是未定义的行为。

在扩展中声明 ivars 和在实现中直接声明有什么区别?

在第 4 个示例中,它是一个全局 C 变量,它不是您的类的实例变量。

什么时候应该在变量名前加下划线 (_)?

只要你想,只要坚持不懈地去做。总是或从不。

于 2013-02-03T17:46:14.163 回答
2

问题1,例2:Class中实现的方法foo和bar对Class的实例是可见的。如果 foo 和 bar 没有在单独的头文件中声明并且实现文件不可用,则另一个类将不知道 foo 和 bar 的存在。foo 和 bar 是私有方法;Class 的实例仍将响应 foo 和 bar 消息。此外,如果另一个类尝试向 foo 和 bar 发送消息,Xcode 将标记警告,因为 Xcode 无法验证(没有头文件中的声明) foo 和 bar 存在。相比之下,示例 1 的 bar 声明允许任何其他类将消息 bar 发送到 Class 的实例。如果@interface Class 位于另一个类#import 的头文件中,Xcode 也不会为任何消息标记错误。

在问题 2 中,示例 4:mySortedArray 是在 Class 中以局部范围声明的局部不可变数组。示例 3 中的 mySortedArray 是 NSArray 类型的实例变量,其他创建 Class 实例的类可以访问。

于 2013-02-03T17:48:41.163 回答
1

希望subclass-category-and-extensions可能对您有所帮助。

于 2013-11-14T17:16:30.763 回答
0

关于类扩展和类别的优秀解释,

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html

于 2013-04-21T18:58:17.880 回答