zoukankan      html  css  js  c++  java
  • iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式

    iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式

      说明:

      1)该文简短介绍在iOS开发中遍历字典、数组和集合的几种常见方式。

      2)该文对应的代码可以在下面的地址获得:https://github.com/HanGangAndHanMeimei/Code

    一、使用for循环

      要遍历字典、数组或者是集合,for循环是最简单也用的比较多的方法,示例如下: 

    复制代码
     1 //普通的for循环遍历
     2 -(void)iteratorWithFor
     3 {
     4     //////////处理数组//////////
     5     NSArray *arrayM = @[@"1",@"2",@"3",@"4"];
     6     NSInteger arrayMCount = [arrayM count];
     7     for (int i = 0; i<arrayMCount; i++) {
     8         NSString *obj = arrayM[i];
     9         NSLog(@"%@",obj);
    10     }
    11 
    12     //////////处理字典//////////
    13     NSDictionary *dictM = @{@"1":@"one",@"2":@"two",@"3":@"three"};
    14     NSArray *dictKeysArray = [dictM allKeys];
    15     for (int i = 0; i<dictKeysArray.count; i++) {
    16         NSString *key = dictKeysArray[i];
    17         NSString *obj = [dictM objectForKey:key];
    18         NSLog(@"%@:%@",key,obj);
    19     }
    20 
    21     //////////处理集合//////////
    22     NSSet * setM = [[NSSet alloc] initWithObjects:@"one",@"two",@"three",@"four", nil];
    23     NSArray *setObjArray = [setM allObjects];
    24     for (int i = 0; i<setObjArray.count; i++) {
    25         NSString *obj = setObjArray[i];
    26         NSLog(@"%@",obj);
    27     }
    28 
    29     //////////反向遍历----降序遍历----以数组为例
    30     NSArray *arrayM2 = @[@"1",@"2",@"3",@"4"];
    31     NSInteger arrayMCount2 = [arrayM2 count] - 1;
    32 
    33     for (NSInteger i = arrayMCount2; i>0; i--) {
    34         NSString *obj = arrayM2[i];
    35         NSLog(@"%@",obj);
    36     }
    37 }
    复制代码

    优点:简单

    缺点:由于字典和集合内部是无序的,导致我们在遍历字典和集合的时候需要借助一个新的『数组』作为中介来处理,多出了一部分开销。

    二、使用NSEnumerator遍历

    NSEnumerator的使用和基本的for循环类似,不过代码量要大一些。示例如下:

    复制代码
     1 //使用NSEnumerator遍历
     2 -(void)iteratorWithEnumerator
     3 {
     4     //////////处理数组//////////
     5     NSArray *arrayM = @[@"1",@"2",@"3",@"4"];
     6     NSEnumerator *arrayEnumerator = [arrayM objectEnumerator];
     7     NSString *obj;
     8     while ((obj = [arrayEnumerator nextObject]) != nil) {
     9         NSLog(@"%@",obj);
    10     }
    11 
    12     //////////处理字典//////////
    13     NSDictionary *dictM = @{@"1":@"one",@"2":@"two",@"3":@"three"};
    14     NSEnumerator *dictEnumerator = [dictM keyEnumerator];
    15     NSString *key;
    16     while ((key = [dictEnumerator nextObject]) != nil) {
    17         NSString *obj = dictM[key];
    18         NSLog(@"%@",obj);
    19     }
    20 
    21 
    22     //////////处理集合//////////
    23     NSSet * setM = [[NSSet alloc] initWithObjects:@"one",@"two",@"three",@"four", nil];
    24     NSEnumerator *setEnumerator = [setM objectEnumerator];
    25     NSString *setObj;
    26     while ((setObj = [setEnumerator nextObject]) != nil) {
    27         NSLog(@"%@",setObj);
    28     }
    29 
    30 
    31     //////////反向遍历----降序遍历----以数组为例
    32     NSArray *arrayM2 = @[@"1",@"2",@"3",@"4"];
    33     NSEnumerator *arrayEnumerator2 = [arrayM2 reverseObjectEnumerator];
    34     NSString *obj2;
    35     while ((obj2 = [arrayEnumerator2 nextObject]) != nil) {
    36         NSLog(@"%@",obj2);
    37     }
    38 
    39 }
    复制代码

    优点:对于不同的数据类型,遍历的语法相似;内部可以简单的通过reverseObjectEnumerator设置进行反向遍历。

    缺点:代码量稍大。

    三、使用for...In遍历

    在Objective-C 2.0 中增加了for ...In 形式的快速遍历。此种遍历方式语法简洁,速度飞快。示例如下:

    复制代码
     1 //使用for...In进行快速遍历
     2 -(void)iteratorWithForIn
     3 {
     4     //////////处理数组//////////
     5     NSArray *arrayM = @[@"1",@"2",@"3",@"4"];
     6     for (id obj in arrayM) {
     7         NSLog(@"%@",obj);
     8     }
     9 
    10     //////////处理字典//////////
    11     NSDictionary *dictM = @{@"1":@"one",@"2":@"two",@"3":@"three"};
    12     for (id obj in dictM) {
    13         NSLog(@"%@",dictM[obj]);
    14     }
    15 
    16     //////////处理集合//////////
    17     NSSet * setM = [[NSSet alloc] initWithObjects:@"one",@"two",@"three",@"four", nil];
    18     for (id obj in setM) {
    19         NSLog(@"%@",obj);
    20     }
    21 
    22     //////////反向遍历----降序遍历----以数组为例
    23     NSArray *arrayM2 = @[@"1",@"2",@"3",@"4"];
    24     for (id obj in [arrayM2 reverseObjectEnumerator]) {
    25         NSLog(@"%@",obj);
    26     }
    27 }
    复制代码

    优点:1)语法简洁;2)效率最高;

    缺点:无法获得当前遍历操作所针对的下标。

    四、基于Block的遍历方式

    基于Block的方式来进行遍历是最新引入的方法。它提供了遍历数组|字典等类型数据的最佳实践。示例如下:

    复制代码
     1 //基于块(block)的遍历方式
     2 -(void)iteratorWithBlock
     3 {
     4     //////////处理数组//////////
     5     NSArray *arrayM = @[@"1",@"2",@"3",@"4"];
     6     [arrayM enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
     7         NSLog(@"%zd--%@",idx,obj);
     8     }];
     9 
    10     //////////处理字典//////////
    11     NSDictionary *dictM = @{@"1":@"one",@"2":@"two",@"3":@"three"};
    12     [dictM enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
    13         NSLog(@"%@:%@",key,obj);
    14     }];
    15 
    16     //////////处理集合//////////
    17     NSSet * setM = [[NSSet alloc] initWithObjects:@"one",@"two",@"three",@"four", nil];
    18     [setM enumerateObjectsUsingBlock:^(id  _Nonnull obj, BOOL * _Nonnull stop) {
    19         NSLog(@"%@",obj);
    20     }];
    21 
    22     //////////反向遍历----降序遍历----以数组为例
    23     NSArray *arrayM2 = @[@"1",@"2",@"3",@"4"];
    24     [arrayM2 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    25         NSLog(@"%zd--%@",idx,obj);
    26     }];
    27 }
    复制代码

    优点:1)遍历时可以直接从block中获得需要的所有信息,包括下标、值等。特别相对于字典而言,不需要做多余的编码即可同时获得key和value的值。

       2)能够直接修改block中key或者obj的类型为真实类型,可以省去类型转换的工作。

       3)可以通过NSEnumerationConcurrent枚举值开启并发迭代功能。

    说明:基于Block的遍历方式在实现反向遍历的时候也非常简单,使用enumerateObjectsWithOptions方法,传递NSEnumerationReverse作为参数即可,在处理遍历操作的时候推荐基于Block的遍历方式。

    五、使GCD中的dispatch_apply函数

      使用GCD中的dispatch_apply函数也能实现字典、数组等的遍历,该函数比较适合处理耗时较长、迭代次数较多的情况。示例如下:

    复制代码
     1 //使用GCD中的dispatch_apply函数
     2 -(void)iteratorWithApply
     3 {
     4     //////////处理数组//////////
     5     NSArray *arrayM = @[@"1",@"2",@"3",@"4"];
     6 
     7     //获得全局并发队列
     8     dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
     9 
    10     dispatch_apply(arrayM.count, queue, ^(size_t index) {
    11         NSLog(@"%@--%@",arrayM[index],[NSThread currentThread]);
    12     });
    13 }
    复制代码

    优点:开启多条线程并发处理遍历任务,执行效率高。

    缺点:1)对于字典和集合的处理需借助数组;2)无法实现反向遍历。

  • 相关阅读:
    Centos 7 zabbix 实战应用
    Centos7 Zabbix添加主机、图形、触发器
    Centos7 Zabbix监控部署
    Centos7 Ntp 时间服务器
    Linux 150命令之查看文件及内容处理命令 cat tac less head tail cut
    Kickstart 安装centos7
    Centos7与Centos6的区别
    Linux 150命令之 文件和目录操作命令 chattr lsattr find
    Linux 发展史与vm安装linux centos 6.9
    Linux介绍
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5303622.html
Copyright © 2011-2022 走看看