美文网首页代码片段ios 进阶i看不完别走。。。
iOS可变数组在遍历过程中如何删除元素?

iOS可变数组在遍历过程中如何删除元素?

作者: luzsyn | 来源:发表于2018-09-09 13:57 被阅读238次

    在之前的面试中,面试官问我一个项目中的问题:在可变数组的遍历过程中,删除其中的元素,会发生什么问题?

    我们都知道,在数组的遍历过程中,不要删除数组中的元素,会引起crash,可是今天发现并不是所有的循环方式都会造成crash。

    下面,我们写一段代码进行测试:

    //我们有一个可变数组
    NSMutableArray *mArr = [NSMutableArray arrayWithObjects:@1, @2, @3, @4, @5, @6, nil];
    
    // 普通的循环遍历方式
    for (NSUInteger i = 0; i < mArr.count; i++) {
       [mArr removeObjectAtIndex:i];
    }
    NSLog(@"%@", mArr);
    //打印结果为:2, 4, 6,而且程序没有crash
    
    // 使用迭代器遍历
    [mArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
       [mArr removeObject:obj];
    }];
    NSLog(@"%@", mArr);
    //打印结果为:2, 4, 6,而且程序没有crash
    
    // 使用for-in遍历
    for (NSNumber *obj in mArr) {
       [mArr removeObject:obj];
    }
    NSLog(@"%@", mArr);
    // 程序crash,
    // Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x6000002588d0> was mutated while being enumerated.'
    

    所以在可变数组的遍历过程中,根据不同的遍历方式,会产生不同的问题。

    那么,如果想在遍历过程中,删除数组的元素,该怎么处理呢

    大众的做法是新建一个可变数组,把要想保留的元素,加入到新的数组,方法是可行的,有没有更好的解决方案呢?

    答案是有的。采用逆序遍历

    // 逆序遍历
    [mArr enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
       [mArr removeObject:obj];
    }];
    
    // 逆序遍历
    for (NSNumber *obj in [mArr reverseObjectEnumerator]) {
       [mArr removeObject:obj];
    }
    

    这样,程序就不会crash,数组中的元素也成功移除了。

    补充
    在实际开发中,笔者建议要谨慎使用,要多加测试,笔者在使用分割字符串后,初始化一个可变数组进行删除操作就crash了。

    相关文章

      网友评论

      • 孤单雨凉:为什么移除的元素不是按照index移除的

      本文标题:iOS可变数组在遍历过程中如何删除元素?

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