Sian 发表于 2014-3-23 13:59:30

深入研究NSArray的遍历方法enumerateObjectsUsingBlock:

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做为实参传给block
      // id obj = self;
      
      // 调用传进来的block体,并将循环中的相关参数传到block中去,方便方法调用者确定遍历输出的形式;
      block(self, i, &isStop);
      
      /***********block体的一个示例*************
         
         NSLog(@"%d - %@", i, self);
         
         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 = ;
   
    // 定义一个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;
      }
    };
   
    // 调用该方法完成遍历功能
    ;

    return 0;
}
输出结果:2014-03-23 13:21:57.565 Enumerate 0 - One2014-03-23 13:21:57.567 Enumerate 1 - TwoProgram ended with exit code: 0
页: [1]
查看完整版本: 深入研究NSArray的遍历方法enumerateObjectsUsingBlock: