Премахване на обект от NSMutableArray

Случайно попаднах на следния пряк път при настройване на for цикъл (пряк път в сравнение с примерите от учебниците, които използвах):

for (Item *i in items){ ... }

За разлика от по-дългия формат:

for (NSInteger i = 0; i < [items count]; i++){ ... } //think that's right

Ако използвам по-кратката версия, има ли начин да премахна елемента, който в момента се повтаря (т.е. „i“)? Или трябва да използвам по-дългия формат?


person Ben Packard    schedule 03.05.2010    source източник
comment
Първият for цикъл е известен като подобрения FOR цикъл, а вторият е старият стандартен FOR цикъл. Научавам това, когато правя моето сертифициране по Java.   -  person Popeye    schedule 11.08.2012
comment
Ако наистина трябва да премахнете елементи от масива, докато го итерирате и не можете да ги премахнете след това, като използвате removeObjectsInArray: или removeObjectsAtIndexes:, както предложи @Vladimir, винаги можете да итерирате върху копие на оригиналния масив.   -  person Tiago    schedule 04.08.2014


Отговори (5)


Не можете да премахвате обекти от масив, докато бързо изброявате това:

номерирането е „безопасно“ – изброителят има защита от мутации, така че ако се опитате да промените колекцията по време на изброяването, се предизвиква изключение.

Както и да е, защо трябва да променяте контейнера си, докато го изброявате? Помислете за съхраняване на елементи, които трябва да бъдат изтрити, и ги премахнете от контейнера си, като използвате метода removeObjectsInArray: или removeObjectsAtIndexes:.

person Vladimir    schedule 03.05.2010
comment
Благодаря. Променям го, докато го изброявам, защото е временна опашка. Премествам всички елементи в друг масив. - person Ben Packard; 03.05.2010
comment
Ако премествате всички обекти в друг масив, опитайте следното: [destinationArray addObjectsFromArray: sourceArray]; [sourceArray removeAllObjects]; - person JeremyP; 04.05.2010
comment
Страхотен отговор! Работи като чар! - person Groot; 27.11.2012

Просто добавете ключова дума break; след премахване на елемента...

for(id item in items) {
    if([item isEqual:itemToDelete]) {
        [items removeObject:item];
        break;
    }
}
person RaiderF    schedule 13.10.2011
comment
@Abdullah71 с идентификатор, който никога не използвате *. - person rptwsthi; 05.07.2013
comment
Това ще премахне един обект и ще спре итерацията, като по този начин ще пропусне възможни други обекти, които трябва да бъдат премахнати. Така че използвайте това само ако трябва да премахнете от нула до един обект на итерация. - person marsbear; 18.08.2016

Колекция Objective-C не трябва да се променя по време на изброяване.

Можете да използвате този вариант за изтриване на обекти от колекция:

for (NSInteger i = items.count - 1; i >= 0 ; i--) {
   [items removeObjectAtIndex:i];
}
person serhii    schedule 03.09.2015
comment
Мисля, че това е най-краткият начин да го направите правилно, като се има предвид, че е добре с вашата бизнес логика да обхождате масива отзад напред. - person marsbear; 18.08.2016

Първият цикъл е цикъл "за всеки" в Objective C.

*i е указател към директния елемент в items-Array (през повечето време това ще бъде NSMutableArray).

По този начин можете да работите директно върху артикула:

[items removeObject: i];

Това (би трябвало) да работи - в момента не работя на моя Mac и не мога да го проверя. Въпреки това може да се окаже, че Objective-C предотвратява премахването на обекти по време на повторение на колекцията (това е доста често срещано в повечето езици).

person BergmannF    schedule 03.05.2010
comment
Наистина е така, че не можете да премахнете (или промените) NSMutableArray, докато изброявате върху него, така че извикването removeObject: ще предизвика изключение. (както е обяснено от Владимир в неговия отговор) - person Nick Forge; 03.05.2010

Използвам този код за това:

for (NSUInteger i = [items count] - 1; ; i--) {
     [items removeObjectAtIndex:i];
}
person slava    schedule 05.10.2015
comment
Само докато получа -1... тогава се срива :) - person marsbear; 18.08.2016