开发者

Getting exception as "Collection was mutated while being enumerated"

I am getting the Collection was mutated while being enumerated exception when I am using this code can any one suggest me how to get out of this.

PaymentTerms * currentElement;
for (currentElement in termsArray)
{
    printf("\n currentElement Value........%s",[currentElement.days UTF8String]);
    printf("\n Str value...%s",[Str UTF8String]);
    NSRange range = [currentElement.days rangeOfString:Str options:NSCaseInsensitiveSearch];
    if(!(range.location != NSNotFound))
    {
        PaymentTerms *pTerm1 = [[PaymentTerms alloc]init];
        pTerm1.days = Str;
        printf("\n  pTerm1.days...%s",[ pTerm1.days UTF8String]);
        [termsArray addObject:pTerm1];
    }   
}

Hope I get quick response f开发者_高级运维rom ur side. Thank in advance, Monish.


You cannot change array while you're enumerating it. As a workaround you should accumulate new objects in temporary array and add them after enumeration:

PaymentTerms * currentElement;
NSMutableArray* tempArray = [NSMutableArray array];
for (currentElement in termsArray)
{
    NSRange range = [currentElement.days rangeOfString:Str options:NSCaseInsensitiveSearch];
    if(!(range.location != NSNotFound))
    {
       PaymentTerms *pTerm1 = [[PaymentTerms alloc]init];
       pTerm1.days = Str;
       [tempArray addObject:pTerm1];
       [pTerm1 release];
    }   
}
[termsArray addObjectsFromArray: tempArray];

P.S. do not forget to release pTerm1 object you create - your code contains memory leak

In respond to poster's comment (and actual task) - I think the easiest way to make bool flag indicating if day value was found in cycle. If not - add new object after cycle ends:

PaymentTerms * currentElement;
BOOL dayFound = NO;
for (currentElement in termsArray)
{
    NSRange range = [currentElement.days rangeOfString:Str options:NSCaseInsensitiveSearch];
    if(range.location != NSNotFound)
        dayFound = YES;
}
if (!dayFound)
     // Create and add new object here


This line [termsArray addObject:pTerm1]; will throw that exception. You CANNOT add/delete an element from an array inside a for each loop. for (currentElement in termsArray)


Yes...we cannot enumerate while the array is getting updated...This might be irritating for the programmers who are from ActionScript background.Some times things go worse like "You even dont get a crash or intimation at runtime when you update an array count while it is being enumerated"-The execution just behaves abnormally at that time.

Btw you can go for this type of implementation where you can have minor changes to your code.

 for (int i=0 ; i< termsArray.count ;i++)  //counting termsArray on every iteration
 {
  id currentElement  = [ termsArray objectAtIndex:i];
  ......
  .....
 }

Of-course,This(i< termsArray.count) might seem bad as we are calculating the count for every iteration...And thats the trick here to have minor changes.But I would strongly recommend VLADIMIR's implementation as its clear for reading.


you are adding an object to your collection as you are looping over it, thats whats causing the error. your if statement is nested inside the for


The error occurs because you are adding new objects to termsArray within the for loop

  • Create a new empty array (e.g.newTermsArray)
  • In the first loop create and add these new items to newTermsArray
  • Then you will need a second loop to add the items from newTermsArray back into the original termsArray


Just dealt with the same bug in a rather complex app. The solution is simple - create a copy and work with the copy of array (and remove it from the original if you want. Then discard the copy.

for(CharacterModelNode* node in self.allPlayers)
{
   // Some operation that may mutate allPlayers (ex: player dies from poison damage and is removed from this array at some other part of an app)

}

//workaround in some cases - create a copy of array and run operations that can kill player on this array (it will not be mutated anywhere else in the app

NSArray* allPlayersCopy = [self.allPlayers copy];

for(CharacterModelNode* node in allPlayersCopy)
{
    [node.character refreshBuffs];
}


use try and catch for handling exception in nsmutable array

@try {
    //code for accessing element.

    }
    @catch (NSException *exception) {


       /// show exception here

    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜