遍历数组时移除数组中元素造成程序崩

本文介绍了一个iOS开发中常见的问题:在遍历数组的同时删除元素导致程序崩溃。提供了两种解决方案,一种是使用临时数组,另一种是通过block实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天对项目中的一个功能进行改进时,出现了程序崩溃,后来定位到bug所在处,经过一番研究,解决了。直接贴代码,如下。



错误日志:Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7fc7f162c1d0> was mutated while being enumerated.'


#import "ViewController.h"


@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    

    //[self testError]; //错误

    //[self testSolve1]; //解决方法1

    //[self testSolve2]; //解决方法2

}


- (void)testError {

    

    NSMutableArray *array = [NSMutableArrayarrayWithObjects:@1,@2,@3,@4,@5,@6,nil];

    for (NSNumber *numin array) {

        if ([num isEqualToNumber:@4]) {

            NSLog(@"删除数组中的数字4");

            [array removeObject:num];

        }

    }

    //for循环去遍历一个数组,然后删除该数组中的一些元素的操作,就会出现程序崩溃的情况。因为一个数组不能同时有一个线程去读取,然后另一个线程去写,所以出错

}


//解决方法1:定义一个一模一样的临时数组,遍历临时数组然后操作原数组

- (void)testSolve1 {

    

    NSMutableArray *array = [NSMutableArrayarrayWithObjects:@1,@2,@3,@4,@5,@6,nil];

    NSMutableArray *tempArray = [NSMutableArrayarrayWithArray:array];

    for (NSNumber *numin tempArray) {

        if ([num isEqualToNumber:@4]) {

            NSLog(@"删除数组中的数字4");

            [array removeObject:num];

        }

    }

    NSRange range = NSMakeRange(0, [array count]);

    NSArray *subArray = [array subarrayWithRange:range];

    NSLog(@"打印所有元素:%@",subArray);

}

//解决方法2:利用block来操作,原理:找到符合的条件之后,暂停遍历,然后修改数组的内容

- (void)testSolve2 {

    

    NSMutableArray *array = [NSMutableArrayarrayWithObjects:@1,@2,@3,@4,@5,@6,nil];

    [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx,BOOL * _Nonnull stop) {

        if ([obj isEqualToValue:@4]) {

            *stop = YES;

        }

        if (*stop) {

            [array removeObject:obj];

            NSLog(@"打印数组所有元素:%@",array);

        }

    }];

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end


//解决




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值