2009-05-22 28 views

回答

14

NSSet用于您经常希望测试成员资格的一个对象,但不关心排序并且不需要包含重复对象的集合。 NSSet不以任何特定顺序存储其对象;相反,该类明确地设计为有效地测试集合中是否存在对象

NSCountedSet也是如此,但NSCountedSet也保留计数重复的对象。

所以一言以蔽之:使用时,你很关心测试会员一组,而不是仅仅保持对象的集合(其中一些可能被复制,通过某种类型的isEqualTo方法决定)。

11

在midpadi上继续使用NSArray的许多用途都应该用NSSet替换。 NSSet是独特对象的集合。 NSArray是有序对象的集合。如果你的对象没有固有的顺序并且是唯一的,你应该使用NSSet。

我经常在模型层中保留一个NSSet,并让需要订单的UI组件创建自己的NSArrays。例如,考虑由“伙伴”组成的“好友列表”的情况。好友列表本身是无序的;它只是一个集合。对象需要是唯一的。然而,在用户界面层,您需要一个订单,甚至可能希望将同一个好友放在多个组中(例如,喜爱和离线)。但这些都是UI问题,模型层不应该担心它们。

NSSet *buddies = [buddyList allBuddies]; 
BOOL isBuddy = [buddyList containsObject:buddy]; 

NSArray *buddyList = [[buddyList allBuddies] sortedAraryUsingSelector:[self buddySortSelector]]; 

当一个新的伙伴显示出来,好友列表将发布一个通知(BuddyListDidAddBuddiesNotification),其包括在其用户信息添加好友的NSSet中。因此,观察此事件的UI元素可以按照适当的排序顺序将好友插入到列表中。这使列表动画变得非常简单,如果在模型层中保留所有已排序的版本,这将变得更加困难。

当你有两个NSSets时,很容易找出它们之间的差异,并构建一系列删除并添加到另一个(再次,对动画有用)。用NSArray做这件事要复杂得多。

所以我的建议是默认为NSSet。实际需要订购时,您应该只使用NSArray。不幸的是,大多数人都这么做了。

+0

核心数据本质上与NSSets一起工作 – Abizern 2009-05-22 15:01:57

4

除了其他答案,其中主要是集合,但不是很多计数集,你可能想知道什么时候最好使用计数集。计数集对于加权或其他统计算法等事情很有用:最后,您最终可以使用存储的计数来对其内容的有序数组进行排序。

另一种选择是将表格或引用计数器/垃圾回收器的形式进行分配。使用计数的集合将使得包含测试(即,返回一个现有的相同对象,而不是创建一个新对象 - 类似于CoreData在内部所做的),同时对它所包含的值执行一种引用计数,因为一旦对象的计数达到0,该对象只会被该对象释放。