我是靠谱客的博主 忧虑云朵,最近开发中收集的这篇文章主要介绍Objective-C集合遍历的几种方式集合遍历的几种方式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

集合遍历的几种方式

  • 集合遍历的几种方式
      • 简单for循环
      • NSEnumerator枚举遍历
      • for in快速遍历
      • 基于块的遍历

简单for循环


//
定义集合时尽量采用语法糖的格式,简洁高效
NSDictionary *dictionary = @{ @"1" : @"a",
@"2" : @"b",
@"3" : @"c",
@"4" : @"d"
};
NSArray *keys = dictionary.allKeys;
for (int i = 0; i < dictionary.count; i++) {
NSLog(@"%@ : %@", keys[i], dictionary[keys[i]]);
}
简单for循环在这里不会赘述,但是我会拿它与for in快速遍历做一个对比,我们普遍认为for in快速遍历一定比for循环快,但是只有在集合中元素很多的情况下这才是对的,当集合中元素很少的情况下for循环比for in循环更快。具体的对比可以参考孙源的这篇博客[iOS 中集合遍历方法的比较和技巧](http://blog.sunnyxx.com/2014/04/30/ios_iterator/)

NSEnumerator枚举遍历


NSDictionary *dictionary = @{ @"1" : @"a",
@"2" : @"b",
@"3" : @"c",
@"4" : @"d"
};
NSEnumerator *enumerator = [dictionary objectEnumerator];
id value = nil;
while (value = [enumerator nextObject]) {
NSLog(@"%@",value);
}
这种形式不得不令人想起Java的迭代器,值得一提的也就是nextObject这个方法了,这个方法返回集合中下一个元素,若没有下一个元素返回nil。这种遍历方式在开发中也很少用到。
使用NSEnumerator对数组进行遍历的时候,还可以倒序遍历:
NSArray *array = @[ @"one",
@"two",
@"three",
@"fourth"
];
NSEnumerator *arrayEnumerator = [array reverseObjectEnumerator];
while (value = [arrayEnumerator nextObject]) {
NSLog(@"%@",value);
}
值得注意的是:若对可变容器进行遍历时,不可对可变容器修改。如下代码会导致crash。

NSEnumerator *enumerator = [dictionary objectEnumerator];
id value = nil;
while (value = [enumerator nextObject]) {
NSLog(@"%@",value);
[dictionary setValue:@"q" forKey:@"a"];
}

为什么会出现这种原因?
官网上关于NSEnumerator这样说:
The enumerator subclasses used by NSArray, NSDictionary, and NSSet retain the collection during enumeration. When the enumeration is exhausted, the collection is released.
大致的意思是(这次百度翻译挺给力,没有瞎扯淡,毕竟四级没过的人,看官方文档,呵呵):
通过NSArray,NSDictionary使用枚举器类、集合枚举过程中保留和不可变。当枚举耗尽时,集合被释放。
这样就没困惑了。

for in快速遍历


NSDictionary *dictionary = @{ @"1" : @"a",
@"2" : @"b",
@"3" : @"c",
@"4" : @"d"
};
for (NSString *key in dictionary) {
NSLog(@"%@ : %@", key, dictionary[key]);
}
这种遍历集合的方法在开发中最常用,因为它形式简洁、效率也高。它的缺点是无法访问到集合下标,而且、也是非常值得注意的一点,若对可变容器进行遍历时,不可对可变容器修改。如下代码会导致crash:
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:@"1" forKey:@"a"];
[dictionary setObject:@"2" forKey:@"b"];
[dictionary setObject:@"3" forKey:@"c"];
[dictionary setObject:@"4" forKey:@"d"];
for (NSString *key in dictionary) {
NSLog(@"%@ : %@", key, dictionary[key]);
[dictionary setObject:@"111" forKey:@"a"];
}

Excuse me?这个错误好熟悉?
我们知道for in又称NSFastEnumeration,而NSFastEnumeration又采用了NSEnumerator,所以也有这种缺陷。

基于块的遍历

NSLog(@"------------------------");
NSArray *array = @[ @"one",
@"two",
@"three",
@"fourth"
];
[array enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%@ %lu", obj, (unsigned long)idx);
}];
[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%@ %lu", obj, (unsigned long)idx);
}];
NSLog(@"------------------------");
[array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%@ %lu", obj, (unsigned long)idx);
}];
NSLog(@"========================");

运行结果是这样滴:

2016-11-06 13:25:24.274 集合遍历的几种方式[4298:979287] ------------------------
2016-11-06 13:25:24.274 集合遍历的几种方式[4298:979287] one 0
2016-11-06 13:25:24.275 集合遍历的几种方式[4298:979287] two 1
2016-11-06 13:25:24.275 集合遍历的几种方式[4298:979287] three 2
2016-11-06 13:25:24.275 集合遍历的几种方式[4298:979287] fourth 3
2016-11-06 13:25:24.275 集合遍历的几种方式[4298:979287] fourth 3
2016-11-06 13:25:24.276 集合遍历的几种方式[4298:979287] three 2
2016-11-06 13:25:24.276 集合遍历的几种方式[4298:979287] two 1
2016-11-06 13:25:24.276 集合遍历的几种方式[4298:979287] one 0
2016-11-06 13:25:24.276 集合遍历的几种方式[4298:979287] ------------------------
2016-11-06 13:25:24.277 集合遍历的几种方式[4298:979287] one 0
2016-11-06 13:25:24.277 集合遍历的几种方式[4298:979287] three 2
2016-11-06 13:25:24.277 集合遍历的几种方式[4298:979324] two 1
2016-11-06 13:25:24.277 集合遍历的几种方式[4298:979325] fourth 3
2016-11-06 13:25:24.278 集合遍历的几种方式[4298:979287] ========================
对于一个方法,官方这样描述:
Executes a given block using the objects in the array at the specified indexes.By default, the enumeration starts with the first object and continues serially through the array to the last element specified by indexSet. You can specify NSEnumerationConcurrent and/or NSEnumerationReverse as enumeration options to modify this behavior.This method executes synchronously.ImportantIf the block parameter or the indexSet is nil this method will raise an exception.
值得注意的是:
1. 这个方法从集合第一个元素开始,顺序遍历该集合,这和打印结果一样
2. 该方法同步执行这和打印结果一样
对于第二个方法,比第一个方法多了一个参数NSEnumerationReverse,从结果可以看出:遍历顺序为倒序,同步执行。
对与第三个方法,指定了NSEnumerationConcurrent 这个参数,从结果可以看出是无序的,为什么会无序?
因为该块内的遍历是并发执行的。

最后

以上就是忧虑云朵为你收集整理的Objective-C集合遍历的几种方式集合遍历的几种方式的全部内容,希望文章能够帮你解决Objective-C集合遍历的几种方式集合遍历的几种方式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部