2011-01-14 43 views
19

是否有NSDictionary返回密钥的原因是NSArray而不是NSSet?该文档已经指出,数组中的键的顺序是未定义的,使用一个集合听起来合乎逻辑。为什么不[NSDictionary allKeys]返回一个集合?

+4

有趣的问题。不得不怀疑,这是纯粹是因为NSSet在NeXTSTEP以前的日子里,NSArray就在那里,但这完全是我的猜测。 – 2011-01-14 17:56:28

+0

不错的问题,我也会假设它,因为NSArray是第一个,是比一套更广泛使用/理解/已知的结构。我不记得,但也许当你返回键数组时,它会对它们进行排序,提供一种更简单的迭代方法? – 2011-01-14 18:00:32

+0

[File an enhancement request。](http://bugreporter.apple.com/) – 2011-01-14 18:26:41

回答

2

集合在API设计中往往被忽略。它们大部分时间都会包含在内,但通常会在所有其他标准数据结构之后。除此之外,除了最近的NSFastEnumeration之外,Objective-C中没有通用的集合或顺序协议 - 每个集合类都完全独立于其他所有集合类,并且很难在API之后切换到集合已经写成返回数组。

1

猜测是苹果采用NSArray所有的地方(以及大多数程序员也一样),所以这个选择顺其自然 - 现在改变它将付出了高昂的代价。而如果在内部使用数组,一个不可变数组的副本比为了数学优雅而创建一个集合要便宜得多。

还要注意的是NSSetNSArray没有一个共同的父(当然,除了NSObject,当然),所以这个抽象接口也是不可能的(除了返回一些符合NSFastEnumeration)。

只是疯狂的猜测,当然。 ;-)

0

我的猜测是,由于-allKeys返回副本钥匙(它不是由字典支持),创建一个NSSet是一个很大的开销(构建树或哈希表或其他)时相比之下,只是将按键倾倒成平面阵列。

-3

使用使用C++,std :: map提供对其键的访问权限作为集合。返回的集合甚至是“现场”,该集合反映了当前正在进行的一组键。当然你也可以自由复制。

0

通常你会想要做的东西按键,在这种情况下,它更容易使用这种方法的NSDictionary:

- (NSSet<KeyType> *)keysOfEntriesPassingTest:(BOOL (^)(KeyType key, ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0); 

这样可以节省时间,因为现在你不需要使用过滤您的阵列谓词,你可以在这里执行你的测试,然后你回来。简单。

此外,你可以通过并发枚举选项,这个版本的方法,充分利用多处理器的并发:

- (NSSet<KeyType> *)keysOfEntriesWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (^)(KeyType key, ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0); 
相关问题