Bug-iOS: Collection was mutated while being enumerated.

[objc] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. //init a NSArray  
  2. NSMutableArray *arr2 = [NSMutableArray array];  
  3. for (int i=0; i<10; ++i) {  
  4.     NSMutableDictionary *d = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%d", i], @"a", nil nil];  
  5.     [arr2 addObject:d];  
  6. }  
  7.   
  8. //Wrong  
  9. for (NSMutableDictionary *s in arr2) {  
  10.     if ([s[@"a"] isEqualToString:@"3"]) {  
  11.         [arr2 removeObject:s]; //while here is safe for s[@"a"] = @"eeee";  
  12.     }  
  13. }  
  14.   
  15.   
  16. //Safe 1.  
  17. [arr2 enumerateObjectsUsingBlock:^(NSMutableDictionary *obj, NSUInteger idx, BOOLBOOL *stop) {  
  18.     if ([obj[@"a"] isEqualToString:@"3"]) {  
  19.         *stop = YES;  
  20.         [arr2 removeObject:obj]; // or obj[@"a"] = @"4ewewewe";  
  21.     }  
  22. }];  
  23.   
  24. //Safe 2.  
  25. NSArray *tmp = [NSArray arrayWithArray:arr2];  
  26. for (NSMutableDictionary *s in tmp) {  
  27.     if ([s[@"a"] isEqualToString:@"3"]) {  
  28.         s[@"a"] = @"eeee";  
  29.         [arr2 removeObject:s];  
  30.     }  
  31. }  

利用block來操作,根據查閱資料,發現block便利比for便利快20%左右,這個的原理是這樣的:

找到符合的條件之後,暫停遍歷,然後修改數組的內容


PS: 搜一句補充的話

//forin 循環中的便利內容不能被改變, 是因爲如果改變其便利的內容會少一個, 而系統是不會允許這個發生的所以就會crash...但是當改變最後一個的內容時, 就不會crash, 是因爲此時遍歷已經結束, 結束之後對內容做修改是允許的 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章