1、遍历数组的方法有多种,最常见的有for循环、while循环、以及调用数组自身的遍历方法;
2、NSArray的遍历方法"enumerateObjectsUsingBlock:",是如何实现对数组元素逐个遍历的呢?
3、通过分类的方式,定义一个类似"enumerateObjectsUsingBlock:"的方法来研究数组遍历方法的本质;
4、创建一个NSArray的分类Enumerate,并且在分类中实现一个方法"sianEnumerateObjectsUsingBlock:";
5、该方法类型与"enumerateObjectsUsingBlock:"完全相同,无返回值,形参为(id, NSUInteger, BOOL *);
6、方法内部通过一个for循环再调用block体来实现对数组的遍历;
7、该方法通过block的形参,实现了普通遍历的各种参数,如元素体、元素序号以及部分遍历(随时停止);
8、可以思考一下,为何需要传递一个BOOL *指针;
参考代码:
NSMutableArray+Enumerate.h- //
- // NSMutableArray+Enumerate.h
- // Enumerate
- //
- // Created by yusian on 14-3-22.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- @interface NSMutableArray (Enumerate)
- // 声明一个类似"enumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block"的方法
- - (void) sianEnumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block;
- @end
复制代码 NSMutableArray+Enumerate.m- //
- // NSMutableArray+Enumerate.m
- // Enumerate
- //
- // Created by yusian on 14-3-22.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import "NSMutableArray+Enumerate.h"
- @implementation NSMutableArray (Enumerate)
- // 遍历方法实现
- - (void) sianEnumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block
- {
- // 遍历一般都采用for循环的方式实现
- for (int i = 0; i < self.count; i ++) {
-
- // 定义一个BOOL变量用来判断是否需要退出,实现部分遍历
- BOOL isStop = NO;
-
- // 定义一个对象变量接收数组元素,并传到block中去,可供block调用,可省略,直接将self[i]做为实参传给block
- // id obj = self[i];
-
- // 调用传进来的block体,并将循环中的相关参数传到block中去,方便方法调用者确定遍历输出的形式;
- block(self[i], i, &isStop);
-
- /***********block体的一个示例*************
-
- NSLog(@"%d - %@", i, self[i]);
-
- if (i == 1) {
- *(&isStop) = YES;
- }
- ***************************************/
-
- // 如果isStop为YES,则退出循环,遍历结束,由于作用域的原因,外部赋值无法直接修改内部BOOL变量的值
- // 所以通过地址传递完成直接修改内部BOOL值的目的,从而结束跳出循环
- if (isStop) {
- break;
- }
-
- }
- }
- @end
复制代码 main.m- //
- // main.m
- // Enumerate
- //
- // Created by yusian on 14-3-22.
- // Copyright (c) 2014年 小龙虾论坛. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "NSMutableArray+Enumerate.h"
- int main()
- {
- // 定义一个可变数组
- NSMutableArray * array = [NSMutableArray arrayWithObjects:@"One", @"Two", @"Three", nil];
-
- // 定义一个block,并且为无返回值形参分别为id、NSUInteger、BOOL *类型的block
- void (^block)(id, NSUInteger, BOOL *);
-
- // 给block赋值,block为方法实现体的补充
- block = ^(id obj, NSUInteger idx, BOOL *stop){
-
- // block内容为输出"%ld - %@"
- NSLog(@"%ld - %@", idx, obj);
-
- // 如果idx == 1,传个YES给stop指针指向的地址,可实现遍历结束的功能
- if (idx == 1) {
- *stop = YES;
- }
- };
-
- // 调用该方法完成遍历功能
- [array sianEnumerateObjectsUsingBlock:block];
- return 0;
- }
复制代码 输出结果:2014-03-23 13:21:57.565 Enumerate[534:303] 0 - One 2014-03-23 13:21:57.567 Enumerate[534:303] 1 - Two Program ended with exit code: 0
|