iOS开发之使用block块进行数据遍历的方法
看了一篇文章,发现遍历数组、字典中的数据时,除了使用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块进行数据遍历的方法的更多相关文章
- iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)
iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值) 使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值: 先说一下思想: ...
- iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式
iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...
- iOS开发-Objective-C Block的实现方式
前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量.你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观.顺带一提,苹果很多的接口(A ...
- iOS开发笔记3:XML/JSON数据解析
这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...
- iOS开发——网络Swift篇&NSURL进行数据请求(POST与GET)
NSURL进行数据请求(POST与GET) 使用Swift进行iOS开发时,不可避免的要进行远程的数据获取和提交. 其数据请求的方式既可能是POST也可能是GET.同不管是POST还是GET又可以 ...
- iOS开发备忘录:属性列表文件数据持久化
属性列表文件是一种XML文件,Foundation框架中的数组和字典等都可以于属性列表文件相互转换. NSArray类常用读写属性列表文件的方法: +arrayWithContentsOfFile:类 ...
- iOS开发 - OC - 实现本地数据存储的几种方式二(直接使用sqlite)
连接上一篇文章http://www.cnblogs.com/FBiOSBlog/p/5819418.html. 上一篇文章介绍了OC内部一些方法进行数据的本地存储,其中包括 NSUser类.Plist ...
- iOS开发 - OC - 实现本地数据存储的几种方式一
iOS常用的存储方式介绍 在iOS App开发过程中经常需要操作一些需要持续性保留的数据,比如用户对于App的相关设置.需要在本地缓存的数据等等.本文针对OC中经常使用的一下存储方式做了个整理. 常用 ...
- iOS开发——语法&高级Block练习
高级Block练习 一 .最简单的block使用 使用block的三个步骤:1.定义block变量 2.创建block代码块 3.调用block匿名函数 定义一个block的构成包括:返回值,bloc ...
随机推荐
- [NOI2015]品酒大会
题目描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainb ...
- 51nod 1682 中位数计数
1682 中位数计数基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均 ...
- [UOJ UR #2]树上GCD
来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 看完题目,一般人都能想到 容斥稳了 .这样我们只要统计有多少点对满足gcd是i的倍数. 考虑长链剖分,每次合并的时候,假设我已经求出轻 ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
- Codeforces Round #398 (div.2)简要题解
这场cf时间特别好,周六下午,于是就打了打(谁叫我永远1800上不去div1) 比以前div2的题目更均衡了,没有太简单和太难的...好像B题难度高了很多,然后卡了很多人. 然后我最后做了四题,E题感 ...
- vue loadMore 上拉刷新不能实现的坑
1.如果你写的代码没问题,但依然不能实现上拉刷新效果,那你有可能是缺少了overflow: scroll 2.如果上拉刷新一直在加载状态,需要调用this.$refs.loadmore.onBotto ...
- 如何在Google上下载高清原图
在我们学习和生活中常常一些高清图片作为相关的素材,比如制作PPT.写博文.制作视频都需要大量图片.我们常常会在百度上下载一些图片,但是百度上提供的图片存在很多问题:存在水印.清晰度不够等.而Googl ...
- B/S与C/S架构
1.CS.BS架构定义 CS(Client/Server):客户端----服务器结构.C/S结构在技术上很成熟,它的主要特点是交互性强.具有安全的存取模式.网络通信量低.响应速度快.利于处理大量数据. ...
- Java 反射(二)
作者:郑剑锋链接:https://www.zhihu.com/question/24304289/answer/147529485来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- Android studio安装和问题
一.Android studio的安装 [提示]A.以下Android studio2.2.2版本.(也有新版本) B.以下是用Android studio自带的sdk ①双击安装文件进行安装 ②如果 ...