类集群在公共抽象超类下组合了许多私有具体子类.
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];
这里使用类集群的动机在文档中进行了解释:
Because numbers of different types have many features in common (they can be converted from one type to another and can be represented as strings, for example), they could be represented by a single class. However, their storage requirements differ, so it’s inefficient to represent them all by the same class.
类集群的其他示例包括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子类吗?
最佳答案 你可以用多少种方法构建NSDictionary?
通过创建一个内部可变大小的对象,填充它,然后将其标记为不可变,可以更容易地实现几种方式(initWithContentsOfFile,initWithObjectsAndKeys等).
其他(initWithObjects:forKeys:count:,initWithDictionary,init,@ {})可以通过固定大小(但仍然是暂时可变的)对象很好地服务.
然后你有可变/不可变的变化.
不是简单的类层次结构.从性能,占用空间和创建的对象数量的角度来看,包装类比类层次结构更不可取.
(另外,当然,最重要的答案是:因为Apple发号施令,这就是他们的决定.)