Удалить элементы в цикле for без побочных эффектов?


Могу ли я удалить элементы, которые я просматриваю в цикле Objective-C for без побочных эффектов?

Например, это нормально?

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

3 ответа:

Нет, вы получите ошибку, если мутируете массив во время быстрого перечисления для цикла. Сделайте копию массива, повторите его и удалите из оригинала.

NSArray *itemsCopy = [items copy];

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

[itemsCopy release];

Нет:

Перечисление "безопасно" - перечислитель имеет защиту от мутаций, так что при попытке изменить коллекцию во время перечисления возникает исключение.

Варианты изменения массива, который вы хотите перечислить, приведены в С помощью Перечислителей : либо скопируйте массив и перечислите его, либо создайте набор индексов, который вы используете после цикла.

Удалить можно так:

    //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];
        }
    }