美文网首页
NSMutableArray的遍历及删除

NSMutableArray的遍历及删除

作者: 灵魂老鬼 | 来源:发表于2019-12-16 19:58 被阅读0次

    for循环、快速循环forin、迭代器 NSEnumerator、迭代器的block形式 [array enumeratorObjectsUsingBlock^(id obj, NSUInteger index, BOOL *stop){}]
    本文从遍历元素的效率和删除元素两个方面比较四种遍历方式。

    遍历效率

    测试代码如下:

    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
    long long length = 1000000;
    for (NSInteger i = 0; i < length; i++) {
        ZJZTest *test = [[ZJZTest alloc] init];
        test.name = [NSString stringWithFormat:@"name - %ld", i];
        [array addObject:test];
    }
    
    NSLog(@"循环次数 %lld", length);
    
    //普通for循环
    NSInteger count = array.count;
    NSDate *startTime = [NSDate now];
    for (NSInteger i = 0; i < count; i++) {
        ZJZTest *test = array[i];
        test.name = [NSString stringWithFormat:@"%@ + test", test.name];
    }
    NSDate *endTime = [NSDate now];
    NSLog(@"for 所用时间:%.0f", [endTime timeIntervalSinceDate:startTime] * 1000);
    
    //快速循环遍历forin
    startTime = [NSDate now];
    for (ZJZTest *test in array) {
        test.name = [NSString stringWithFormat:@"%@ + test", test.name];
    }
    endTime = [NSDate now];
    NSLog(@"forin 所用时间:%.0f", [endTime timeIntervalSinceDate:startTime] * 1000);
    
    //迭代器NSEnumerator
    NSEnumerator *enumerator = [array objectEnumerator];
    id obj = nil;
    startTime = [NSDate now];
    while (obj = [enumerator nextObject]) {
        ZJZTest *test = (ZJZTest *)obj;
        test.name = [NSString stringWithFormat:@"%@ + test", test.name];
    }
    endTime = [NSDate now];
    NSLog(@"NSEnumerator 所用时间:%.0f", [endTime timeIntervalSinceDate:startTime] * 1000);
    
    //迭代器的block形式实现
    startTime = [NSDate now];
    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        ZJZTest *test = obj;
        test.name = [NSString stringWithFormat:@"%@ + test", test.name];
    }];
    endTime = [NSDate now];
    NSLog(@"enumerateObjectsUsingBlock 所用时间:%.0f", [endTime timeIntervalSinceDate:startTime] * 1000);
    

    结果对比:


    3.jpg 2.jpg 1.jpg

    对比可以看出:

    1、快速遍历forin的效率始终比普通for循环高。
    2、NSEnumerator和enumerateObjectsUsingBlock的效率始终相差无几。
    3、随着遍历次数的增加forin的效率明显高于for、NSEnumerator、enumerateObjectsUsingBlock。

    删除满足条件的元素

    测试代码如下:

    //普通for循环
    for (NSInteger i = 0; i < array.count; i++) {
        ZJZTest *test = array[i];
        if ([test.name isEqualToString:@"test - 5"]) {
            [array removeObject:test];
        }
    }
    
    //快速循环遍历forin
    for (ZJZTest *test in array) {
        if ([test.name isEqualToString:@"test - 5"]) {
            [array removeObject:test];
        }
    }
    
    //迭代器NSEnumerator
    NSEnumerator *enumerator = [array objectEnumerator];
    id obj = nil;
    while (obj = [enumerator nextObject]) {
        ZJZTest *test = (ZJZTest *)obj;
        if ([test.name isEqualToString:@"test - 5"]) {
            [array removeObject:test];
        }
    }
    
    //迭代器的block形式实现
    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        ZJZTest *test = obj;
        if ([test.name isEqualToString:@"test - 5"]) {
            [array removeObject:test];
        }
    }];
    

    结论:除了forin之外,其他三种方式都可以删除满足条件的元素,而采用forin快速循环遍历,删除满足条件的元素时会造成程序的crush。不可删除的原因,可以参照 关于Objective-C的for in

    相关文章

      网友评论

          本文标题:NSMutableArray的遍历及删除

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