美文网首页
iOS 开发之循环遍历

iOS 开发之循环遍历

作者: _Joeyoung_ | 来源:发表于2017-09-24 18:59 被阅读32次

周末闲来无事,翻看到了自己以前在新浪博客上发的博文,真心吐槽新浪博客真不适合写技术贴(排版太丑 哈哈),索性今天就移到简书上来吧 ~ 知识点很简单,就是方便以后涉及到了便于查阅。废话不多说,开始动工~

在编程中经常需要列举collection中的元素,当前的Object-C语言有多种办法来实现循环遍历的功能.在此对这几种循环遍历总结了一下,希望对大家有所帮助.

1.for循环 基本遍历,功能有限.

    NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
    for (int i = 0; i<anyArr.count; i++) {
        id object = anyArr[i];
        NSLog(@"-- %@ --",object);
    }
    
    //数组是‘有序的‘,字典 与 set 都是‘无序的’,
    //需要先获取字典里的所有键 或是 set里的所有对象
    NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
    NSArray *keyArr = [dic allKeys];
    for (int i = 0; i<keyArr.count; i++) {
        id key = keyArr[i];
        id value =dic[key];
        NSLog(@"-- %@ --",value);
    }
                          
    NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
    NSArray *setArr = [set allObjects];
    for (int i = 0; i<setArr.count; i++) {
        id object = setArr[i];
        NSLog(@"-- %@ --",object);
    }

2.使用 NSEnumerator 循环遍历

NSEnumerator 是抽象类,其中定义了两个方法,
供其子类实现:

 //获取枚举中所有对象,以数组形式返回
 @property (readonly, copy) NSArray<ObjectType> *allObjects;

 //返回枚举中的下个对象,如果枚举中的全部对象都已返回,再次调用返回nil,表示到达枚举末端
 - (nullable ObjectType)nextObject;
    //NSArray
    NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
    NSEnumerator *enumerator = [anyArr objectEnumerator];
    id object;
    while ((object = [enumerator nextObject]) != nil) {
        NSLog(@"-- %@ --",object);
    }
    
    //NSDictionary
    NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
    NSEnumerator *dicEnumerator = [dic keyEnumerator];
    id key;
    while ((key = [dicEnumerator nextObject]) != nil) {
        id value = dic[key];
        NSLog(@"-- %@ --",value);
    }
    
    //NSSet
    NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
    NSEnumerator *setEnumerator = [set objectEnumerator];
    id setObject;
    while ((setObject = [setEnumerator nextObject]) != nil) {
        NSLog(@"-- %@ --",setObject);
    }

3.快速遍历 (如果某个类的对象支持快速遍历,就可以宣称自己遵从名为 NSFastEnumeration 的协议)

    //NSArray
    NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
    for (id object in anyArr) {
        NSLog(@"-- %@ --",object);
    }
    
    //NSDictionary
    NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
    for (id key in dic) {
        id value = dic[key];
        NSLog(@"-- %@ --",value);
    }
    
    //NSSet
    NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
    for (id object in set) {
        NSLog(@"-- %@ --",object);
    }
    
    //NSEnumerator 对象也实现了 NSFastEnumeration 协议,可以用来执行反向遍历
    NSArray *any = @[@"1",@"2",@"3",@"4"];
    for (id object in [any reverseObjectEnumerator]) {
        NSLog(@"-- %@ --",object);
    }

4.基于‘块’的遍历

    //NSArray
    /*
    - (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block
    遍历是既能获取对象,也能获取对象对应的下标
     */
    NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
    [anyArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"-- %@ --",obj);
        //可以设置中断遍历的条件
        if (idx == 2) {
            *stop = YES;
        }
    }];
    
    //DSDictionary
    /*
     - (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block
     */
    NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
    [dic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        NSLog(@"-- %@ --",obj);
        if ([key isEqualToString:@"name"]) {
            *stop = YES;
        }
    }];
    
    //NSSet (NSOrderedSet 有序集合)
    /*
     - (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))block
     */
    NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
    [set enumerateObjectsUsingBlock:^(id  _Nonnull obj, BOOL * _Nonnull stop) {
        NSLog(@"-- %@ --",obj);
    }];
    
    /**
     - (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block
     - (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block
          - (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))block
     数组,字典,set都可以执行反向遍历。
     只有在遍历数组或者是有序set等有顺序的collection时,上面的方法才有意义。
     NSEnumerationOptions 是一个枚举类型
     typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions) {
         //并发方式执行迭代,底层会通过GCD来处理并发执行事宜,此时执行顺序是’无序‘的
         NSEnumerationConcurrent = (1UL << 0),
         //反向遍历
         NSEnumerationReverse = (1UL << 1),
     };
     */

要点:

  • 1.遍历collection有四种方式.最基本的办法是for循环,其次是NSEnumerator遍历法及快速遍历法,最新,最先进的方式则是"块枚举法";
  • 2."块枚举法"本身能通过GCD来并发执行遍历操作,无须另行编写代码.而采用其他遍历方式则无法轻易实现这一点;
  • 3.若提前知道待遍历的collection含有何种对象,则应该修改块签名,指出对象的具体类型.

千里之行,始于足下!

相关文章

网友评论

      本文标题:iOS 开发之循环遍历

      本文链接:https://www.haomeiwen.com/subject/ipzkextx.html