iOS实现遍历的几种方法

遍历的目的是获取集合中的某个对象或执行某个操作,所以能满足这个条件的方法都可以作为备选:

  • for
  • for in
  • enumerateObjectsUsingBlock
  • enumerateObjectsWithOptions(NSEnumerationConcurrent)
    更多方案请参考 iOS 中集合遍历方法的比较和技巧
NSArray *arr = @[@"0", @"1", @"3", @"4", @"6"];
经典 for 循环
for (int i = 0; i < [arr count]; i++) {
     NSLog(@"%zi %@", i, arr[i]);
}
for in
for (NSString *string in arr) {
      NSLog(@"%@", string);
}
enumerateObjectsUsingBlock
[arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"%zi %@", idx, obj);
        if ([obj isEqualToString:@"2"]) {
            NSLog(@"------ %zi %@", idx, obj);
            *stop = YES;
        }
}];
enumerateObjectsWithOptions: usingBlock:
typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions) {
    NSEnumerationConcurrent = (1UL << 0),
    NSEnumerationReverse = (1UL << 1),

Options 指定 NSEnumerationReverse 时 ,会进行倒叙排列;
Options 指定 NSEnumerationConcurrent 顺序,底层通过GCD来处理并发执行事宜,具体实现可能会用到dispatch group。也就是说,这个会用多线程来并发实现,并不保证按照顺序执行

[arr enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"idx=%ld, id=%@", idx, obj);
        //当需要结束循环的时候,调用stop,赋予YES
        if (idx ==3) {
            *stop = YES;
        }
}];

NSArray 的两个方法:
reverseObjectEnumerator 也能实现倒叙排序
objectEnumerator 正序排序

    for (NSString *string in [arr reverseObjectEnumerator]) {
        NSLog(@"*-*-*- %@", string);
    }
enumerateObjectsAtIndexes: options: usingBlock:

NSIndexSet 类代表一个不可变的独特的无符号整数的集合,称为索引,因为使用它们的方式。这个集合被称为索引集 唯一的,有序的,无符号整数的集合

  • 索引集合的创建方式
[NSIndexSet indexSetWithIndex:1];//1.创建一个索引集合,根据索引值
[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,8)];//2.创建一个索引集合,根据一个NSRange对象
  • enumerateObjectsAtIndexes 使用方法
[arr enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,3)] options:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"\n\nidx=%ld, id=%@", idx, obj);
    }];

遍历字典 key value

    NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:@"obj1",@"key1",@"obj2",@"key2", nil];
    [dic enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
        NSLog(@"dict >>> value for key %@ is %@ ", key, value);
        if ([@"key2" isEqualToString:key]) {
            NSLog(@"dict >>> %@ %@", key, value);
            *stop = YES;
        }
}];

对比

  • for循环 、for in、和 EnumerateObjectsUsingBlock 的比较
  • 对于集合中对象数很多的情况下,for in 的遍历速度非常之快,但小规模的遍历并不明显(还没普通for循环快)
  • Value查询index的时候, 面对大量的数组推荐使用 enumerateObjectsWithOptions的并行方法.
  • 遍历字典类型的时候, 推荐使用enumerateKeysAndObjectsUsingBlock,block版本的字典遍历可以同时取key和value(forin只能取key再手动取value)

你可能感兴趣的:(iOS实现遍历的几种方法)