Objective c Apple标题包含多个类别

Objective c Apple标题包含多个类别,objective-c,cocoa,categories,Objective C,Cocoa,Categories,在阅读一些Apple头文件时,我注意到它们使用同一对象的类别声明了多个接口 例如:NSDictionary.h @interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> //methods @end @interface NSDictionary (NSExtendedDictionary) //methods @end @interface

在阅读一些Apple头文件时,我注意到它们使用同一对象的类别声明了多个接口

例如:
NSDictionary.h

@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>

//methods

@end

@interface NSDictionary (NSExtendedDictionary)

//methods

@end

@interface NSDictionary (NSDictionaryCreation)

//methods

@end
@接口NSDictionary:NSObject
//方法
@结束
@接口NSDictionary(NSExtendedDictionary)
//方法
@结束
@接口NSDictionary(NSDictionaryCreation)
//方法
@结束
这纯粹是一种帮助组织代码的方法吗?作为一个用户,使用
NSDictionary
时,所有类别中的所有方法都会出现,这没有什么区别


这还有其他有用的结果吗?

很肯定这是一个组织问题。我不知道在公共头文件中使用类别还有什么好处。(在将新方法插入现有类时,它们当然很有用)

编辑: 看看维基百科。他们似乎有一个相当权威的答案:

在Objective-C的设计过程中,主要关注的问题之一是大型代码库的可维护性。结构化编程世界的经验表明,改进代码的主要方法之一是将代码分解成更小的部分。Objective-C借用并扩展了Smalltalk实现中的类别概念,以帮助实现这一过程。[9]


似乎也很合适,因为系统标题来自NeXT——这些人将以这种方式编写代码。

nielsbot的想法是正确的,但分类有一个特定的技术原因。您可以将实现放在单独的文件中。(从技术上讲,不同的翻译单位。)

文件1:

@implementation NSDictionary
...
@end
@implementation NSDictionary (NSExtendedDictionary)
...
@end
@implementation NSDictionary (NSDictionaryCreation)
...
@end
文件2:

@implementation NSDictionary
...
@end
@implementation NSDictionary (NSExtendedDictionary)
...
@end
@implementation NSDictionary (NSDictionaryCreation)
...
@end
文件3:

@implementation NSDictionary
...
@end
@implementation NSDictionary (NSExtendedDictionary)
...
@end
@implementation NSDictionary (NSDictionaryCreation)
...
@end

此外,像NSDictionary和NSArray这样的容器类具有基于大小等度量的多个支持数据结构,因此以这种方式组织的效果特别好,因为你可以根据方法所操作的数据结构来区分它们。我不确定维基百科的参考文献是否真的解释了这一点——我认为它更多的是指创建一个基类,比如“NSDictionary”,然后使用一个类别来扩展它,而不必进行子类化或其他会导致创建更大片段的事情。那是我的读物anyway@Bavarious总之,在这种情况下:值得一提的是,如果您声明了一个类别,那么您将得到一个警告,然后编写一个
@implementation
部分,该部分不会实现您声明的所有方法。但是,拥有没有
@implementation
部分的类别没有什么错;从历史上看,您可能在例如
NSObject
上使用此类类别作为创建非正式协议的手段,但苹果现在使用并推荐
@protocol
,改为使用
@optional
关键字。反之亦然:您可以为类别编写@implementation,而无需创建@interface部分。对于现有类的私有附加组件,我一直都在这样做。再说一遍,这是组织代码的好方法。