Greg
Greg

Reputation: 34818

Remove items in a for loop without side effects?

Can I remove items that I am looping through in an Objective-C for loop without side effects?

For example, is this ok?

for (id item in items) {
   if ( [item customCheck] ) {
      [items removeObject:item];   // Is this ok here?
}

Upvotes: 5

Views: 3282

Answers (3)

user3761851
user3761851

Reputation: 33

you can remove like this:

    //Create array
    NSMutableArray* myArray = [[NSMutableArray alloc] init];

    //Add some elements
    for (int i = 0; i < 10; i++) {
        [myArray addObject:[NSString stringWithFormat:@"i = %i", i]];
    }

    //Remove some elements =}
    for (int i = (int)myArray.count - 1; i >= 0 ; i--) {
        if(YES){
            [myArray removeObjectAtIndex:i];
        }
    }

Upvotes: 0

jscs
jscs

Reputation: 64012

Nope:

Enumeration is “safe”—the enumerator has a mutation guard so that if you attempt to modify the collection during enumeration, an exception is raised.

Options for changing an array that you want to enumerate through are given in Using Enumerators: either copy the array and enumerate through, or build up an index set that you use after the loop.

Upvotes: 3

McCygnus
McCygnus

Reputation: 4215

No, you'll get an error if you mutate the array while in a fast enumeration for loop. Make a copy of the array, iterate over it, and remove from your original.

NSArray *itemsCopy = [items copy];

for (id item in itemsCopy) {
   if ( [item customCheck] )
      [items removeObject:item];   // Is this ok here
}

[itemsCopy release];

Upvotes: 12

Related Questions