forin遍历数组并增删其元素导致崩溃

本文探讨了遍历NSMutableArray时删除元素导致的崩溃问题,并提供了三种安全的解决方案:使用for循环、临时变量及enumerateObjectsUsingBlock方法。
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:@[@"1", @“2", @“3", @“4", @“5"]];

  for (NSString *str in array) {
      if ([str isEqualToString:@“3"]) {
          [array removeObject:str];
      }
  }
NSLog(@“数组:%@“,array);

崩溃错误:<__NSArrayM: 0xb550c30> was mutated while being enumerated.’

当程序出现这个提示的时候,是因为用快速遍历forin遍历数组,又同时增或删这个数组里面的内容,导致数组count发生变化,猜测在forin快速遍历的内部有个内置的不会动态改变个数的计数器, 当你的数组做出增删后, 计数器并没有相应的增减, 这样就会导致继续通过计数器获取数组, 造成数组越界。

  The enumerator raises an exception if you modify the collection while enumerating 
  //这句话说明苹果是不建议使用NSFastEnumeration(forin)的时候, 一边遍历一边修改集合

  ou send "nextObject" repeatedly to a newly created NSEnumerator object to 
  have it return the next object in the original collection. When the collection 
  is exhausted, nil is returned. You cannot “reset” an enumerator after it has 
  exhausted its collection. To enumerate a collection again, you need a new enumerator.
  //这句话要注意, nextObject是一个对象方法, 他的作用是取出集合中的一个元素后, 通过这个方法取出并返回"原始集合"中的下一个元素, 当集合遍历结束后, 返回nil. 并且你在遍历的过程中, 不能重新设置遍历器, 直到这个集合遍历结束

  It is not safe to modify a mutable collection while enumerating through it. 
  Some enumerators may currently allow enumeration of a collection that is modified, 
  but this behavior is not guaranteed to be supported in the future.
  //从上述看出来, 当使用快速遍历器的时候, 修改一个可变的集合, 是相当不安全的操作, 可能造成一些不可预知的问题
解决方案:

1.使用for循环 (array.count动态获取了array的个数,故不会崩溃)

 for (int i = 0; i < array.count; i++) {
    if (...) {
        // do sth ;
    }
}

2.使用临时变量(缺点:数据量大的时候,开辟新的内存,导致内存增加,用完最好手动释放)

NSArray *tempArray = [NSArray arrayWithArray:array];
for (id obj in tempArray) {
    if ([obj iskindOfClass:[Object class]]) {
     // do sth ;
    }
}
tempArray = nil;

3.enumerateObjectsUsingBlock(苹果推荐)

[array enumerateObjectsUsingBlock:^(NSMutableDictionary *obj, NSUInteger idx, BOOL *stop) {
    if (...) {
         // do sth
         *stop = YES;
    }
}];
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值