年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6651|回复: 0

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

[复制链接]
  • TA的每日心情

    2024-10-15 10:05
  • 签到天数: 372 天

    [LV.9]以坛为家II

    发表于 2014-3-23 13:59:30 | 显示全部楼层 |阅读模式
    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
    1. //
    2. //  NSMutableArray+Enumerate.h
    3. //  Enumerate
    4. //
    5. //  Created by yusian on 14-3-22.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import <Foundation/Foundation.h>
    9. @interface NSMutableArray (Enumerate)
    10. // 声明一个类似"enumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block"的方法
    11. - (void) sianEnumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block;
    12. @end
    复制代码
    NSMutableArray+Enumerate.m
    1. //
    2. //  NSMutableArray+Enumerate.m
    3. //  Enumerate
    4. //
    5. //  Created by yusian on 14-3-22.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import "NSMutableArray+Enumerate.h"
    9. @implementation NSMutableArray (Enumerate)
    10. // 遍历方法实现
    11. - (void) sianEnumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block
    12. {
    13.     // 遍历一般都采用for循环的方式实现
    14.     for (int i = 0; i < self.count; i ++) {
    15.         
    16.         // 定义一个BOOL变量用来判断是否需要退出,实现部分遍历
    17.         BOOL isStop = NO;
    18.         
    19.         // 定义一个对象变量接收数组元素,并传到block中去,可供block调用,可省略,直接将self[i]做为实参传给block
    20.         // id obj = self[i];
    21.         
    22.         // 调用传进来的block体,并将循环中的相关参数传到block中去,方便方法调用者确定遍历输出的形式;
    23.         block(self[i], i, &isStop);
    24.         
    25.         /***********block体的一个示例*************
    26.          
    27.          NSLog(@"%d - %@", i, self[i]);
    28.          
    29.          if (i == 1) {
    30.             *(&isStop) = YES;
    31.          }
    32.          ***************************************/
    33.         
    34.         // 如果isStop为YES,则退出循环,遍历结束,由于作用域的原因,外部赋值无法直接修改内部BOOL变量的值
    35.         // 所以通过地址传递完成直接修改内部BOOL值的目的,从而结束跳出循环
    36.         if (isStop) {
    37.             break;
    38.         }
    39.         
    40.     }
    41. }
    42. @end
    复制代码
    main.m
    1. //
    2. //  main.m
    3. //  Enumerate
    4. //
    5. //  Created by yusian on 14-3-22.
    6. //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    7. //
    8. #import <Foundation/Foundation.h>
    9. #import "NSMutableArray+Enumerate.h"
    10. int main()
    11. {
    12.     // 定义一个可变数组
    13.     NSMutableArray * array = [NSMutableArray arrayWithObjects:@"One", @"Two", @"Three", nil];
    14.    
    15.     // 定义一个block,并且为无返回值形参分别为id、NSUInteger、BOOL *类型的block
    16.     void (^block)(id, NSUInteger, BOOL *);
    17.    
    18.     // 给block赋值,block为方法实现体的补充
    19.     block = ^(id obj, NSUInteger idx, BOOL *stop){
    20.    
    21.         // block内容为输出"%ld - %@"
    22.         NSLog(@"%ld - %@", idx, obj);
    23.         
    24.         // 如果idx == 1,传个YES给stop指针指向的地址,可实现遍历结束的功能
    25.         if (idx == 1) {
    26.             *stop = YES;
    27.         }
    28.     };
    29.    
    30.     // 调用该方法完成遍历功能
    31.     [array sianEnumerateObjectsUsingBlock:block];
    32.     return 0;
    33. }
    复制代码
    输出结果:
    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

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-12-22 16:50 , Processed in 0.088049 second(s), 19 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表