类集群在公共抽象超类下对许多私有具体子类进行分组。 Apple's documentation以NSNumber
为例;以下每个便捷构造函数都返回NSNumber
的另一个私有子类:
NSNumber *aChar = [NSNumber numberWithChar:’a’];
NSNumber *anInt = [NSNumber numberWithInt:1];
NSNumber *aFloat = [NSNumber numberWithFloat:1.0];
NSNumber *aDouble = [NSNumber numberWithDouble:1.0];
此处使用类集群的动机在文档中进行了解释:
由于不同类型的数字具有许多共同特征(例如,它们可以从一种类型转换为另一种类型,并且可以表示为字符串),因此它们可以由单个类表示。但是,它们的存储要求不同,因此将它们全部表示为同一类是无效的。
类群集的其他示例包括NSString
,NSData
,NSArray
和NSDictionary
。基于以上说明,我理解为什么NSString
和NSData
可以作为类集群实现。毕竟,NSString
实例的存储要求可能会有所不同,具体取决于它是使用C字符串还是CFString
进行初始化。
但为什么NSArray
和NSDictionary
?似乎应该将这两个类实现为围绕CFMutableArray
和CFMutableDictionary
的包装器。毕竟,NSDictionary
可以将任何内容存储为键或值;没有人知道存储要求是什么。所以存储CFDictionary似乎是要走的路。
例如,NSDictionary
可以在NSXDictionary
下面实现:
// NSXDictionary.m
@interface NSXDictionary ()
@property (nonatomic, assign) CFMutableDictionaryRef dictionary;
@end
@implementation NSXDictionary
- (instancetype)init {
self = [super init];
if (self) {
_dictionary = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
return self;
}
- (void)dealloc {
CFRelease(_dictionary);
}
- (NSUInteger)count {
return CFDictionaryGetCount(self.dictionary);
}
- (id)objectForKey:(id)aKey {
return CFDictionaryGetValue(self.dictionary, (__bridge const void *)(aKey));
}
@end
我的问题是:为什么NSDictionary
被实现为类集群?将它作为具体类实现并不简单,并且NSMutableDictionary
将它子类化吗?
答案 0 :(得分:2)
您可以使用多少种方法构建NSDictionary?
通过创建一个内部可变大小的对象,填充它,然后将其标记为不可变,可以更容易地实现几种方法(initWithContentsOfFile,initWithObjectsAndKeys等)。
其他(initWithObjects:forKeys:count:,initWithDictionary,init,@{}
)可以通过固定大小(但仍然是暂时可变的)对象很好地服务。
然后你就有了可变/不可变的变体。
不是简单的类层次结构。从性能,占用空间和创建的对象数量的角度来看,包装类比类层次结构更不可取。
(另外,当然,最重要的答案是:因为Apple发号施令,而这就是他们的决定。)
答案 1 :(得分:0)
它是作为类集群实现的,因为它可以返回NSDictionary
或NSMutableDictionary
:
NSMutableDictionary *mutableDict = [dict mutableCopy];
NSDictionary *dict = [mutableDict copy];
像:
NSString/NSMutableString
NSData/NSMutableData
NSArray/NSMutableArray
Apple文档中也指出:
在此链接: