看了一篇文章,发现遍历数组、字典中的数据时,除了使用for循环外,还可以使用block块进行操作,瞬间感觉iOS的语言代码确实有点高大上的感觉,下面就简单的介绍一下这个方法。

首先是最基本的运用形式,

//基于 块(block) 结构的遍历数组方法  enumerate:列举,数
    //参数介绍: obj:值  idx:索引  stop:停止遍历
    NSArray *arr1 = @[@"好", @"好", @"学", @"习", @"天", @"天", @"向",@"上"];
    [arr1 enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        //NSLog(@"输出基于 块(block) 结构的遍历数组方法数组中的值.......%@", obj);
        if ([obj isEqualToString:@"习"]) {
            *stop = YES;
        }
    }];
    
    
    //基于 块(block) 结构的遍历字典方法,字典是无序的,每次值的顺序是不固定的  enumerate:列举,数
    //参数介绍: key:键  obj:值  stop:停止遍历
    NSDictionary *dict1 = @{@"1":@"好好", @"2":@"学习", @"3":@"天天",@"4":@"向上"};
    [dict1 enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        //NSLog(@"输出基于 块(block) 结构的遍历字典方法字典中的值........%@", obj);
        if ([obj isEqualToString:@"向上"]) {
            *stop = YES;
        }
    }];

若已知collection里对象的数据类型,可以修改块签名,知道对象的精确类型后,编译器就可以检测开发者是否调用了该对象所不具有的方法,并在发现问题时报错。

如代码,直接把key和value的类型修改成NSString类型。

//基于 块(block) 结构的遍历字典,如果知道字典中的键、值类型,可以修改块儿中的键、值类型的方法,字典是无序的,每次值的顺序是不固定的  enumerate:列举,数
    //参数介绍: key:键  obj:值  stop:停止遍历
    NSDictionary *dict2 = @{@"1":@"好好", @"2":@"学习", @"3":@"天天",@"4":@"向上"};
    [dict2 enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL * _Nonnull stop) {
        //NSLog(@"基于 块(block) 结构的遍历字典,修改键、值类型的方法字典中的值........%@", obj);
        if ([obj isEqualToString:@"向上"]) {
            *stop = YES;
        }
    }];

//基于 块(block) 结构的 反向 遍历数组方法  enumerate:列举,数   多添加一个参数:NSEnumerationReverse:Reverse:相反,
    //参数介绍: obj:值  idx:索引  stop:停止遍历
    NSArray *arr2 = @[@"好", @"好", @"学", @"习", @"天", @"天", @"向",@"上"];
    [arr2 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        //NSLog(@"基于 块(block) 结构的 反向 遍历数组方法数组中的值.......%@", obj);
        if ([obj isEqualToString:@"习"]) {
            *stop = YES;
        }
    }];

//基于 块(block) 结构的 并发 遍历数组方法  enumerate:列举,数  Concurrent:同时发生的
    //参数是:NSEnumerationConcurrent,也就是可以同时遍历collection中的几个元素,具体数量根据系统资源而定
    //参数介绍: obj:值  idx:索引  stop:停止遍历
    NSArray *arr3 = @[@"好", @"好", @"学", @"习", @"天", @"天", @"向",@"上"];
    NSMutableArray *newArr = [NSMutableArray arrayWithArray:arr3];
    [newArr enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj = [NSString stringWithFormat:@"_%@", obj];
        [newArr replaceObjectAtIndex:idx withObject:obj];
        NSLog(@"基于 块(block) 结构的 并发 遍历数组方法数组中的值.......%@", obj);
//        if ([obj isEqualToString:@"_向"]) {
//            *stop = YES;
//        }
    }];

优缺点总结:

优点:

1、可以完美实现for循环的所有功能;

2、可以方便获取集合中的每一项元素;

3、提供了循环遍历的参数,NSEnumerationReverse用来实现倒序循环。NSEnumerationConcurrent用来实现并发遍历,两个参数可以同时使用;

4、这种循环方式效率高,能够提升程序性能,开发者可以专注于业务逻辑,而不必担心内存和线程的问题;

5、当开启NSEnumerationConcurrent选项时,可以实现for循环和快速遍历无法轻易实现的并发循环功能,系统底层会通过GCD处理并发事宜,这样可以充分利用系统和硬件资源,达到最优的遍历效果;

6、可以修改块签名,当我们已经明确集合中的元素类型时,可以把默认的签名id类型修改成已知类型,比如常见的NSString,这样既可以节省系统资源开销,也可以防止误向对象发送不存在的方法是引起的崩溃。

缺点:

1、很多开发者不知道这种遍历方式;

2、这里使用了block,需要注意在block里容易引起的保留环问题,比如使用self调用方法时,把self转化成若引用即可打破保留环。如:__weak __typeof(self)weakSelf = self 或者 __weak MyController *weakSelf = self; 在block里使用weakSelf即可。

注意:

使用基于块的遍历时是可以修改遍历的元素的,不会导致崩溃,但是如果要删除遍历的元素会导致后面的元素无法遍历而崩溃,解决办法有2种,1、一种是复制一份原集合的副本,对副本进行操作,找出所要操作的元素后再处理原集合;2、使用反向遍历,反向遍历删除元素后不会导致崩溃。

参考文献,原文链接:http://www.jianshu.com/p/d6ef96c862ca

iOS开发之使用block块进行数据遍历的方法的更多相关文章

  1. iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)

    iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)   使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值: 先说一下思想: ...

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

    iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...

  3. iOS开发-Objective-C Block的实现方式

    前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量.你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观.顺带一提,苹果很多的接口(A ...

  4. iOS开发笔记3:XML/JSON数据解析

    这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...

  5. iOS开发——网络Swift篇&NSURL进行数据请求(POST与GET)

    NSURL进行数据请求(POST与GET)   使用Swift进行iOS开发时,不可避免的要进行远程的数据获取和提交. 其数据请求的方式既可能是POST也可能是GET.同不管是POST还是GET又可以 ...

  6. iOS开发备忘录:属性列表文件数据持久化

    属性列表文件是一种XML文件,Foundation框架中的数组和字典等都可以于属性列表文件相互转换. NSArray类常用读写属性列表文件的方法: +arrayWithContentsOfFile:类 ...

  7. iOS开发 - OC - 实现本地数据存储的几种方式二(直接使用sqlite)

    连接上一篇文章http://www.cnblogs.com/FBiOSBlog/p/5819418.html. 上一篇文章介绍了OC内部一些方法进行数据的本地存储,其中包括 NSUser类.Plist ...

  8. iOS开发 - OC - 实现本地数据存储的几种方式一

    iOS常用的存储方式介绍 在iOS App开发过程中经常需要操作一些需要持续性保留的数据,比如用户对于App的相关设置.需要在本地缓存的数据等等.本文针对OC中经常使用的一下存储方式做了个整理. 常用 ...

  9. iOS开发——语法&高级Block练习

    高级Block练习 一 .最简单的block使用 使用block的三个步骤:1.定义block变量 2.创建block代码块 3.调用block匿名函数 定义一个block的构成包括:返回值,bloc ...

随机推荐

  1. [HAOI2016]找相同字符

    题目描述 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 输入输出格式 输入格式: 两行,两个字符串s1,s2,长度分别为 ...

  2. [JSOI2007]祖码Zuma

    题目描述 这是一个流行在Jsoi的游戏,名称为祖玛. 精致细腻的背景,外加神秘的印加音乐衬托,彷佛置身在古老的国度里面,进行一个神秘的游戏——这就是著名的祖玛游戏.祖玛游戏的主角是一只石青蛙,石青蛙会 ...

  3. TopCoder SRM 558 Div 1 - Problem 1000 SurroundingGame

    传送门:https://284914869.github.io/AEoj/558.html 题目简述  一个人在一个n * m棋盘上玩游戏,想要占领一个格子有两个方法: 在这个格子放一个棋子.  这个 ...

  4. 【网络流】【BZOJ1006】【SCOI2007】蜥蜴

    学弟@lher在周末训练赛中出的题目的原题(这个人拿省选题来当作提高组模拟,太丧了...) 题意简析:看题目:) 解题思路:题目显然是最大流. 首先拆点将点权变为边权,然后按照题意对于所有有跳板的点向 ...

  5. hdu 5391 (数论)

    Zball in Tina Town Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Oth ...

  6. python 字典实现简单购物车

    # -*- coding: utf-8 -*-#总金额asset_all=0i1=input('请输入总资产:')asset_all=int(i1)#商品列表goods=[ {'name':'电脑', ...

  7. PTA 邻接表存储图的广度优先遍历(20 分)

    6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...

  8. day04 Java Web 开发入门

    day04 Java Web 开发入门 1. web 开发相关介绍 2. web 服务器 3. Tomcat服务器启动的问题 4. Tomcat目录结构 5. Web应用程序(虚拟目录映射,缺省web ...

  9. Ubuntu搭建owncloud10

    前言: 在此我先吐槽一下.用Centos系统简直是为难我自己,是看到那个系统 感到无比的绝望. 正文: 自己在虚拟机中搭建Ubuntu系统.这里就不说了 安装好之后自己换源.建议的源: 清华源: # ...

  10. 一些重要的计算机网络协议(IP、TCP、UDP、HTTP)

    一.计算机网络的发展历程 1.计算机网络发展 与其说计算机改变了世界,倒不如说是计算机网络改变了世界.彼时彼刻,你我都因网络而有了交集,岂非一种缘分? 计算机与网络发展大致经历如下过程: