遍历

//第一种
[arr enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop){
     NSLog(@ "%ld,%@" ,idx,[arr objectAtIndex:idx]);
}];
//第二种
dispatch_apply([arr count], dispatch_get_global_queue( 0 , 0 ), ^(size_t index){ //并行
     NSLog(@ "%ld,%@" ,index,[arr objectAtIndex:index]);
});
//第三种
dispatch_apply([arr count], dispatch_get_main_queue(), ^(size_t index){ //串行,容易引起主线程堵塞,可以另外开辟线程
     NSLog(@ "%ld,%@" ,index,[arr objectAtIndex:index]);
});
//第四种
for (NSString*str in arr) {
      NSLog(@ "%@" ,str);
}
//第五种,do-while
int i = 0 ;
do {
     NSLog(@ "%@" ,[arr objectAtIndex:i]);
     i++;
} while (i<[arr count]);
 
//第六种,while-do
int j = 0 ;
while (j<[arr count]) {
     NSLog(@ "%@" ,[arr objectAtIndex:j]);
     j++;
}
//第七种,普通for循环
for ( int m = 0 ; m<[arr count]; m++) {
     NSLog(@ "%@" ,[arr objectAtIndex:m]);
}

① 其中第二种方法由于是并行,所以打印出来的东西是随机的,并不是按照顺序打印的

② 第三种容易引起主线程堵塞,所以最好自己另外创建一个线程

倒序遍历

NSArrayNSOrderedSet都支持使用reverseObjectEnumerator倒序遍历,如:

1
2
3
4
NSArray *strings = @[@"1", @"2", @"3"];
for (NSString *string in [strings reverseObjectEnumerator]) {
    NSLog(@"%@", string);
}

这个方法只在循环第一次被调用,所以也不必担心循环每次计算的问题。

同时,使用enumerateObjectsWithOptions:NSEnumerationReverse也可以实现倒序遍历:

1
2
3
[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Sark *sark, NSUInteger idx, BOOL *stop) {
    [sark doSomething];
}];

使用block同时遍历字典key,value

block版本的字典遍历可以同时取key和value(forin只能取key再手动取value),如:

1
2
3
4
NSDictionary *dict = @{@"a": @"1", @"b": @"2"};
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    NSLog(@"key: %@, value: %@", key, obj);
}];

对于耗时且顺序无关的遍历,使用并发版本

1
2
3
[array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(Sark *sark, NSUInteger idx, BOOL *stop) {
    [sark doSomethingSlow];
}];

遍历执行block会分配在多核cpu上执行(底层很可能就是gcd的并发queue),对于耗时的任务来说是很值得这么做的,而且在以后cpu升级成更多核心后不用改代码也可以享受带来的好处。同时,对于遍历的外部是保持同步的(遍历都完成后才继续执行下一行),猜想内部大概是gcd的dispatch_group或者信号量控制。

代码可读性和效率的权衡

虽然说上面的测试结果表明,在集合内元素不多时,经典for循环的效率要比forin要高,但是从代码可读性上来看,就远不如forin看着更顺畅;同样的还有kvc的集合运算符,一些内置的操作以keypath的方式声明,相比自己用for循环实现,一行代码就能搞定,清楚明了,还省去了重复工作;在framework中增加了集合遍历的block支持后,对于需要index的遍历再也不需要经典for循环的写法了。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值