zoukankan      html  css  js  c++  java
  • iOS中数组遍历的方法及比较

     数组遍历是编码中很常见的一种需求,我们来扒一拔iOS里面都有什么样的方法来实现,有什么特点。

          因为ios是兼容C语言的,所以c语言里面的最最常见的for循环遍历是没有问题的。

          本文中用的数组是获取的系统的语言数组,大约有30多个数据,虽然还不够模拟大批量的数据,但对于方法的验证是没有问题的了。

    [objc] view plain copy
    1. NSArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];  
          第一种方法是最最熟悉的C语言演化过来的:
    [objc] view plain copy
    1. for (int i = 0; i<langArray.count; i++) {  
    2.     NSLog(@"langArray[%d]=%@", i, langArray[i]);  
    3. }  
          这个方法最普通,效率也一般,但它也有好处,一是方便针对下标的处理,就是说如果我要处理i==10的情况是很简便的,另一个是可以比较方便的反向遍历。

          Objective-C 1.0里面的NSEnumerator也可以进行遍历,代码如下:

    [objc] view plain copy
    1. NSEnumerator *enumerator = [langArray objectEnumerator];  
    2. id object;  
    3. while ((object = [enumerator nextObject]) != nil) {  
    4.      NSLog(@"langArray=%@", object);  
    5. }  

          这里我们可以看到没有下标了,通过nextObject的方法来遍历。这个方法的好处是对于遍历NSDictionary和NSSet代码也比较类似,不便的是对于下标的处理会不方便,另外反向遍历需要用reverseObjectEnumerator方法。

          objective-c发展到2.0时又有了快速遍历功能,代码如下:

    [objc] view plain copy
    1. for (id object in langArray) {  
    2.     NSLog(@"langArray=%@", object);  
    3. }  

          这里代码简洁清晰,很长时间是我写代码的首选,号称效率也最高,不过不便之处同样明显,如果算法要求知道数组的下标,这个方法就抓瞎了。另外,反向需要通过[langArray reverseObjectEnumerator]来实现。

          等到block出来后,iOS里面新增加了enumerateObjectsUsingBlock:的方法,代码如下:

    [objc] view plain copy
    1. [langArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOLBOOL *stop) {  
    2.     NSLog(@"idx=%d, id=%@", idx, obj);  
    3. }];  

          这里我们看到block里面的参数包括object,下标以及是否停止遍历,应该说,这个能满足基本所有的遍历需求了,有下标,有运行的对象,还有是否继续遍历的标志。不过反向遍历呢?苹果提供了另外一个方法:

    [objc] view plain copy
    1. [langArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOLBOOL *stop) {  
    2.     NSLog(@"idx=%d, id=%@", idx, obj);  
    3. }];  

          这个enumerateObjectsWithOptions:usingBlock:方法比enumerateObjectsUsingBlock:方法多传了一个参数,这个参数指定了遍历的顺序。

          说到这里,如果我们选择正向遍历,那么这两种方法是一样的么?答案也是否定的。在enumerateObjectsWithOptions:usingBlock:方法里面,如果指定了NSEnumerationConcurrent顺序,那么底层通过GCD来处理并发执行事宜,具体实现可能会用到dispatch group。也就是说,这个会用多线程来并发实现,并不保证按照顺序执行,但效率肯定是杠杠的!

          我们来看一下打印结果:

    [objc] view plain copy
    1. 2014-06-17 15:46:44.413 testStoryboard[2703:3503] idx=32, id=hu  
    2. 2014-06-17 15:46:44.413 testStoryboard[2703:1303] idx=16, id=ru  
    3. 2014-06-17 15:46:44.416 testStoryboard[2703:3503] idx=33, id=vi  
    4. 2014-06-17 15:46:44.412 testStoryboard[2703:60b] idx=0, id=zh-Hant  
    5. 2014-06-17 15:46:44.417 testStoryboard[2703:1303] idx=17, id=pl  
    6. 2014-06-17 15:46:44.417 testStoryboard[2703:60b] idx=1, id=zh-Hans  
    7. 2014-06-17 15:46:44.417 testStoryboard[2703:1303] idx=18, id=tr  
    8. 2014-06-17 15:46:44.419 testStoryboard[2703:60b] idx=2, id=en  
    9. 2014-06-17 15:46:44.419 testStoryboard[2703:1303] idx=19, id=uk  
    10. 2014-06-17 15:46:44.421 testStoryboard[2703:60b] idx=3, id=fr  
    11. 2014-06-17 15:46:44.421 testStoryboard[2703:1303] idx=20, id=ar  
    12. 2014-06-17 15:46:44.421 testStoryboard[2703:60b] idx=4, id=de  
    13. 2014-06-17 15:46:44.422 testStoryboard[2703:60b] idx=5, id=ja  
    14. 2014-06-17 15:46:44.422 testStoryboard[2703:60b] idx=6, id=nl  
    15. 2014-06-17 15:46:44.421 testStoryboard[2703:1303] idx=21, id=hr  
    16. 2014-06-17 15:46:44.423 testStoryboard[2703:60b] idx=7, id=it  
    17. 2014-06-17 15:46:44.423 testStoryboard[2703:1303] idx=22, id=cs  
    18. 2014-06-17 15:46:44.423 testStoryboard[2703:60b] idx=8, id=es  
    19. 2014-06-17 15:46:44.424 testStoryboard[2703:1303] idx=23, id=el  
    20. 2014-06-17 15:46:44.424 testStoryboard[2703:60b] idx=9, id=ko  
    21. 2014-06-17 15:46:44.424 testStoryboard[2703:1303] idx=24, id=he  
    22. 2014-06-17 15:46:44.425 testStoryboard[2703:60b] idx=10, id=pt  
    23. 2014-06-17 15:46:44.425 testStoryboard[2703:60b] idx=11, id=pt-PT  
    24. 2014-06-17 15:46:44.425 testStoryboard[2703:1303] idx=25, id=ro  
    25. 2014-06-17 15:46:44.426 testStoryboard[2703:60b] idx=12, id=da  
    26. 2014-06-17 15:46:44.426 testStoryboard[2703:1303] idx=26, id=sk  
    27. 2014-06-17 15:46:44.426 testStoryboard[2703:60b] idx=13, id=fi  
    28. 2014-06-17 15:46:44.426 testStoryboard[2703:1303] idx=27, id=th  
    29. 2014-06-17 15:46:44.427 testStoryboard[2703:60b] idx=14, id=nb  
    30. 2014-06-17 15:46:44.427 testStoryboard[2703:1303] idx=28, id=id  
    31. 2014-06-17 15:46:44.428 testStoryboard[2703:60b] idx=15, id=sv  
    32. 2014-06-17 15:46:44.428 testStoryboard[2703:1303] idx=29, id=ms  
    33. 2014-06-17 15:46:44.429 testStoryboard[2703:1303] idx=30, id=en-GB  
    34. 2014-06-17 15:46:44.429 testStoryboard[2703:1303] idx=31, id=ca  

          从这个结果我们可以看出,确实遍历了整个数组,但并发按照顺序从头到尾——也就是说,用到了dispatch group。这在遍历大数组而有相互独立时对于效率的提高是相当有利的,赞一个!

          在iOS中,除数组外,还有NSDictionary和NSSet数据也是称为collection数据的,遍历有类似的地方,不过遍历没有数组那么频繁,方法上是差不多的。      


         

     
  • 相关阅读:
    navigateTo防止多次跳转
    vue中的绑定class和微信小程序中的绑定class的区别
    js同步和异步
    本地存储和vuex使用对比
    微信小程序页面跳转区别总结
    CAS-技术专区-认证服务器cas-server搭建
    CAS-技术专区-SSO配置完整案例(静态认证+数据库认证)
    SpringCloud-技术专区-实战案例-Zuul整合OAuth2.0认证服务
    OAuth2.0协议专区-SpringCloud安全-集成OAuth2实现身份认证和单点登录
    OAuth2.0协议专区-SpringCloud微服务实战-基于OAUTH2.0统一认证授权的微服务基础架构
  • 原文地址:https://www.cnblogs.com/tangyuanby2/p/7150103.html
Copyright © 2011-2022 走看看