今天对项目中的一个功能进行改进时,出现了程序崩溃,后来定位到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
//解决