113

我在我的应用程序中多次使用 NSSet,但我自己从未创建过一个。

什么时候使用 an 比使用 an 更好NSSetNSArray为什么?

4

11 回答 11

182

Apple 文档中的图像很好地描述了它:

Objective-C 集合

Array是元素的有序(添加时保持顺序)序列

[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];

[1, 2, 3, 4, 6, 4, 1, 2]

Set是一个独特(无重复)的序列元素列表

[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];

[1, 2, 6, 4, 3]
于 2012-06-12T13:17:01.160 回答
174

当集合中项目的顺序不重要时,集合为在集合中查找项目提供了更好的性能。

原因是集合使用哈希值来查找项目(如字典),而数组必须遍历其全部内容才能找到特定对象。

于 2012-06-12T13:14:39.960 回答
67

最好的答案是Apple 自己的文档

在此处输入图像描述

主要区别在于NSArray有序集合和NSSet无序集合。

有几篇文章讨论了两者之间的速度差异,比如这篇文章。如果您正在遍历无序集合,那就NSSet太好了。但是,在许多情况下,您需要做只有 anNSArray才能做的事情,因此您牺牲了这些能力的速度。

NSSet

  • 主要通过比较访问项目
  • 无序
  • 不允许重复

NSArray

  • 可以通过索引访问项目
  • 已订购
  • 允许重复

这就是它的全部内容!让我知道这是否有帮助。

于 2012-06-12T13:18:11.670 回答
12

NSOrderedSet 在 iOS 5+ 中可用,因此主要区别在于您是否想要数据结构中的重复对象。

于 2013-02-08T14:26:54.753 回答
9

NSArray

  1. 有序的数据收集
  2. 允许重复
  3. 它是集合类型对象

NSSet

  1. 无序的数据收集
  2. 不允许重复
  3. 它也是集合类型对象
于 2015-12-08T08:28:50.120 回答
7

数组用于通过索引访问项目。任何项目都可以多次插入到数组中。数组保持其元素的顺序。

集合基本上仅用于检查项目是否在集合中。这些项目没有顺序或索引的概念。你不能在一个集合中拥有一个项目两次。

如果一个数组想要检查它是否包含一个元素,它必须检查它的所有项目。集合旨在使用更快的算法。

你可以想象一个集合,比如没有值的字典。

请注意,数组和集合不是唯一的数据结构。还有其他的,例如队列、堆栈、堆、斐波那契堆。我建议阅读有关算法和数据结构的书。

有关更多信息,请参阅维基百科

于 2012-06-12T13:25:37.000 回答
5
NSArray *Arr;
NSSet *Nset;

Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];

NSLog(@"%@",Arr);
NSLog(@"%@",Nset);

数组

2015-12-04 11:05:40.935 [598:15730] (1, 2, 3, 4, 2, 1)

集合

2015-12-04 11:05:43.362 [598:15730] { ( 3, 1, 2, 5 )}

于 2015-12-04T05:44:46.030 回答
4

主要区别已经在其他答案中给出。

我只想指出,由于集合和字典的实现方式(即使用哈希),应该注意不要将可变对象用作键。

如果一个键发生了变异,那么哈希(可能)也会改变,指向哈希表中的不同索引/存储桶。原始值不会被删除,并且在枚举或询问结构的大小/计数时实际上会被考虑在内。

这可能会导致一些非常难以定位的错误。

于 2014-12-14T07:36:04.023 回答
3

在这里NSArray,您可以找到数据结构和数据结构的非常彻底的比较NSSet

简短的结论:

是的,NSArray 比 NSSet 简单地保持和迭代更快。构建速度快 50%,迭代速度快 500%。教训:如果您只需要迭代内容,请不要使用 NSSet。

当然,如果您需要测试是否包含,请努力避免使用 NSArray。即使你需要迭代和包含测试,你可能仍然应该选择一个 NSSet。如果您需要保持集合有序并测试是否包含,那么您应该考虑保留两个集合(一个 NSArray 和一个 NSSet),每个集合都包含相同的对象。

NSDictionary 的构造比 NSMapTable 慢——因为它需要复制关键数据。它通过更快的查找来弥补这一点。当然,两者有不同的能力,所以大多数时候,这个决定应该是在其他因素上做出的。

于 2016-02-10T13:52:15.913 回答
2

当访问速度至关重要且顺序无关紧要或由其他方式(通过谓词或排序描述符)确定时,您通常会使用Set 。例如,当通过一对多关系访问托管对象时,Core Data 使用集合

于 2016-06-24T09:38:56.933 回答
1

只是为了添加一点,我有时使用 set 来从数组中删除重复项,例如:-

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
于 2018-05-23T10:58:51.973 回答