我刚开始编写Objective-C,有Java背景,不知道人们写Objective-C程序是如何处理私有方法的。
我知道可能会有一些约定和习惯,把这个问题看作是人们在Objective-C中处理私有方法时使用的最佳技术的集合。
请包括一个论点,你的方法张贴时。为什么它是好的?你知道它有哪些缺点,你是如何处理它们的?
至于我目前的发现。
可以使用MyClass中定义的类别[例如MyClass (Private)]。M文件对私有方法进行分组。
这种方法有两个问题:
Xcode(和编译器?)不会检查你是否在相应的@implementation块中定义了私有类别中的所有方法
你必须把@interface放在MyClass的开头声明你的私有类别。m文件,否则Xcode抱怨一个消息像“self可能不响应消息“privateFoo”。
第一个问题可以用空类别来解决[例如MyClass()]。
第二个问题让我很困扰。我希望在文件末尾看到私有方法的实现(和定义);我不知道这是否可能。
There isn't really a "private method" in Objective-C, if the runtime can work out which implementation to use it will do it. But that's not to say that there aren't methods which aren't part of the documented interface. For those methods I think that a category is fine. Rather than putting the @interface at the top of the .m file like your point 2, I'd put it into its own .h file. A convention I follow (and have seen elsewhere, I think it's an Apple convention as Xcode now gives automatic support for it) is to name such a file after its class and category with a + separating them, so @interface GLObject (PrivateMethods) can be found in GLObject+PrivateMethods.h. The reason for providing the header file is so that you can import it in your unit test classes :-).
顺便说一下,至于在.m文件末尾实现/定义方法,你可以通过在.m文件底部实现category来做到这一点:
@implementation GLObject(PrivateMethods)
- (void)secretFeature;
@end
或者使用类扩展(你称之为“空类别”的东西),最后定义这些方法。Objective-C方法可以在实现中以任何顺序定义和使用,因此没有什么可以阻止您将“私有”方法放在文件的末尾。
即使使用类扩展,我也经常会创建一个单独的头文件(GLObject+Extension.h),以便在需要时使用这些方法,模仿“好友”或“受保护”可见性。
因为这个答案是最初编写的,clang编译器已经开始为Objective-C方法进行两次传递。这意味着你可以完全避免声明你的“私有”方法,无论它们是在调用站点的上面还是下面,它们都会被编译器找到。
其他人已经说过,Objective-C中没有私有方法。然而,从Objective-C 2.0(意味着Mac OS X Leopard, iPhone OS 2.0和更高版本)开始,你可以创建一个名为类扩展的空名称(即@interface MyClass())的类别。类扩展的独特之处在于方法实现必须与公共方法放在同一个@implementation MyClass中。所以我的课程结构是这样的:
在.h文件中:
@interface MyClass {
// My Instance Variables
}
- (void)myPublicMethod;
@end
在.m文件中:
@interface MyClass()
- (void)myPrivateMethod;
@end
@implementation MyClass
- (void)myPublicMethod {
// Implementation goes here
}
- (void)myPrivateMethod {
// Implementation goes here
}
@end
我认为这种方法最大的优点是,它允许您根据功能对方法实现进行分组,而不是根据(有时是任意的)公共/私有区分进行分组。