Original URL: http://www.jianshu.com/p/ad80d9443a92
Support original, if need to reprint, please indicate the source
Do you think you really know for...in ... ??
haha haha, I also encountered this error.
The reason, as the name implies, "has changed at the time of enumeration."
For...in ... Using the Fast enumeration nsfastenumerate
When we want to change the data in the array variable or delete the data in the array, we can't use for...in ...
It should be that the Foreach loop in objective-c is similar to that in Java, and is traversed internally with a iterator (iterator) implementation. Regardless of whether in Java or C + +, once the traversed object has been modified, the iterator generated before the modification will be invalidated, so the C + + Primer and Java textbooks have warned against adding or removing collection elements when iterating through the collection with iterator. It seems that the same is true in Objective-c.
One of the Nsarray enumeration operations needs to be noted: when enumerating through mutable arrays, you cannot alter the array container by adding or removing objects like this. If you do this, the enumerator will be confused and you will get undefined results.
So I'm here to give you three different solutions.
1. Using the For Loop ()
for (int i = 0; i < arr.count; i++) { if (...) { // do sth ; } }
2. Using Temporary variables
NSArray *tmp = [NSArray arrayWithArray:arr]; for (id obj in tmp) { if (...) { // do sth ; } }
3.enumerateObjectsUsingBlock (recommended)
[arr enumerateObjectsUsingBlock:^(NSMutableDictionary *obj, NSUInteger idx, BOOL *stop) { if (...) { // do sth *stop = YES; // 相当于break ; stop控制跳出枚举器. } }];
- 2016.04.26 12:34 , a strawberry-eating rock.
2 reviewsAdd a new comment by time sequence • Reverse chronological • Sort by preference
Close your eyes
2/F • 2016.04.14 11:53
The second way, using variables, you mean is to traverse the TMP operation is arr, right. I have a question is to assign to TMP after the operation of ARR this will not cause the mutated while being enumerate this error?
Enjoyed (0) reply
Love to eat Strawberry rock
3/F • 2016.04.26 13:04
Landlord, suggest you should write detailed point, method two add under:
Nsmutablearray *duplicatearray = [Originalarray mutablecopy];
for (id obj in Duplicatearray) {
if ([OB isequaltostring:@ "3"]) {
[Originalarray Removeobject:obj];
}
}
First throw Call stack:
(0x353d088f 0x37777259 0x353d03b3 0x34e576a9 0x34ea914d 0x1252d9 0x16c281 0x16aadb 0x3425f887 0x3425f281 0x3425f911 0x16a 931 0x3425dc59 0x34260817 0X3278DDFB 0x3278dcd0)
Terminate called throwing an exception
First throw Call stack:
(0x353d088f 0x37777259 0x353d03b3 0x34e576a9 0x34ea914d 0x1252d9 0x16c281 0x16aadb 0x3425f887 0x3425f281 0x3425f911 0x16a 931 0x3425dc59 0x34260817 0X3278DDFB 0x3278dcd0)
Terminate called throwing an exception2013-04-08 15:03:06.800 nanguangtv[45122:707] * * Terminating app due to uncaught ex Ception ' nsgenericexception ', Reason: ' * * * Collection <__NSArrayM:0x8ef350> was mutated while being enumerated. '
First throw Call stack:
(0x353d088f 0x37777259 0x353d03b3 0x34e576a9 0x34ea914d 0x1252d9 0x16c281 0x16aadb 0x3425f887 0x3425f281 0x3425f911 0x16a 931 0x3425dc59 0x34260817 0X3278DDFB 0x3278dcd0)
Terminate called throwing an exception (LLDB)
Encounter such a problem. Depressed.
It turns out that I used multiple threads to read one nsmutalearray times out of the error!
Originally, at the same time, different threads simultaneously read and modify the Nsmutalearray.
Encountered a problem, followed a half-day only to find the cause. (The phenomenon is, the customer always said in the process of downloading, after a while the phenomenon of collapse, as long as the download button, do not do anything, and then the periodical began to download the normal, after about 5 minutes, then to see, the program has collapsed) in the "Fashion Media" ipad app, the homepage of the download page, download, will continue to update the download progress on the page, while there is a 15 second timer, every 15 seconds to switch the current display is the men's, women's or art magazine pages. This timer will remove the cover image displayed in the current ScrollView and replace it to automatically replace the page cover.
crashes when prompted:
Collection <UIButtonContent:0x2341234> was mutated while being enumerated
(a search on the internet found a similar problem: ' Nsgenericexception ', Reason: ' * * * * Collection <__NSArrayM:0x8ef350> was mutated while Being enumerated. ' )
According to this hint, think about it, think it should be done in the process of traversal, modified the Nsarray or Nsmutablearray. Later on, this could be a problem with multi-threaded concurrent access, looking at the stack at the time of the crash, and sure enough to find it.
Because when we downloaded, we used block to update the percentage of the download progress bar in a uiscrollview whenever we received the data.
There is another nstimer that will empty all the elements in this uiscrollview over time, and then add them again, as there may be dynamic elements that need to be added or deleted.
At run time, when two threads go to the same time, when the block is going to update this element in the Uiscrollview, the Nstimer may be performing a cleanup operation, so it collapses.
Originally, at the same time, different threads simultaneously read and modify the Nsmutalearray.
WORKAROUND: Avoid multi-threaded at the same time to modify an object, avoid doing the diachronic, the object is modified, according to this idea, you can consider locking, or directly using atomic way to do.
"Go" is mutated while being enumerated do you think you really know for...in ... ??