【发布时间】:2010-10-28 05:29:19
【问题描述】:
我很少使用这两种集合类型,因为我通常使用它们的对应部分,NSArray、NSDictionary 和等效的可变对象。我有一种感觉,我错过了一个在某些情况下可以比其他两个更快的集合。什么时候是使用这些的理想时间以及如何使用?
【问题讨论】:
标签: objective-c cocoa cocoa-touch foundation
我很少使用这两种集合类型,因为我通常使用它们的对应部分,NSArray、NSDictionary 和等效的可变对象。我有一种感觉,我错过了一个在某些情况下可以比其他两个更快的集合。什么时候是使用这些的理想时间以及如何使用?
【问题讨论】:
标签: objective-c cocoa cocoa-touch foundation
NSSet 用于当您经常希望测试对象的成员身份,但不关心排序并且不需要集合包含重复对象时。 NSSet 不以任何特定顺序存储其对象;相反,该类被明确设计为有效地测试对象是否存在在集合中。
NSCountedSet 也是如此,尽管NSCountedSet 也保留了重复对象的计数。
简而言之:当您关心测试成员身份时,请使用集合,而不是仅仅保留一组对象(其中一些可能是重复的,由isEqualTo 决定某种方法)。
【讨论】:
跟进 midpadi,NSArray 的很多用法应该换成 NSSet。 NSSet 是唯一对象的集合。 NSArray 是有序对象的集合。如果你的对象没有固有的顺序并且是唯一的,你应该使用 NSSet。
我经常在模型层保留一个 NSSet,让需要订单的 UI 组件创建自己的 NSArray。例如,考虑由“好友”组成的“好友列表”的情况。好友列表本身是无序的;这只是一个集合。并且对象必须是唯一的。然而,在 UI 层,您需要一个订单,您甚至可能希望将同一个好友放在多个组中(例如收藏夹和离线)。但这些都是 UI 问题,模型层不需要担心。
NSSet *buddies = [buddyList allBuddies];
BOOL isBuddy = [buddyList containsObject:buddy];
NSArray *buddyList = [[buddyList allBuddies] sortedAraryUsingSelector:[self buddySortSelector]];
当有新好友出现时,BuddyList 将发布通知 (BuddyListDidAddBuddiesNotification),其中在其 userInfo 中包含添加好友的 NSSet。因此,观察到这一点的 UI 元素可以以任何合适的排序顺序将好友插入到他们的列表中。这使得列表动画非常容易,如果您在模型层维护所有排序版本,这将更加困难。
当您有两个 NSSet 时,很容易找出它们之间的差异并构造一系列删除和添加以将一个变为另一个(同样,对动画很有用)。使用 NSArray 执行此操作要复杂得多。
所以我的建议是默认使用 NSSet。仅在实际需要订购时才应使用 NSArray。不幸的是,这与大多数人的做法相反。
【讨论】:
NSOrderedSet。核心数据将此用于有序对多关系
除了其他答案(主要讨论集合而不是计数集合)之外,您可能想知道何时最好使用计数集合。计数集对于诸如加权或其他统计算法之类的东西很有用:最后,您最终可以创建一个有序数组,其中包含使用存储的计数排序的内容。
另一种选择是在唯一表中,或以引用计数器/垃圾收集器的形式。使用计数集将启用包含测试(即返回现有的相同对象而不是创建新对象——类似于 CoreData 内部所做的),同时还对其包含的值执行一种引用计数,因为对象只会计数达到 0 时由集合释放。
【讨论】: