Objective-C 2.0 и быстрое перечисление исключений - PullRequest
5 голосов
/ 16 февраля 2009

У меня есть блок кода, похожий на следующий:

for (NSDictionary *tmp in aCollection) {
   if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
   {
      break;
   }
   else
   {
      [aCollection addObject:bar];
       }
 }

Это технически исключение в Objective-C 2.0? Похоже, вы не можете изменить коллекцию с помощью быстрого перечисления. Это результат ошибки:

*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <NSCFArray: 0x396000> was mutated while being enumerated.'

Какой лучший способ решить эту проблему?

Ответы [ 7 ]

12 голосов
/ 16 февраля 2009

Что ж, способ ее решить - не изменять массив (например, добавить объект) при его перечислении:)

Проблема в том, что изменение массива путем добавления / удаления элементов может привести к тому, что значения перечисления станут недопустимыми, и поэтому возникает проблема.

В вашем случае Самый простой способ решить эту проблему - это исправить ошибку в вашем коде. Ваш код выполняет предложение "Добавить еще" для каждого элемента в массиве, и я совершенно уверен, что это не то, что вам нужно.

Попробуйте это;

bool found = false;
for (NSDictionary *tmp in aCollection)
{
   if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
   {
      found = true;
      break;
   }
}

if (!found)
{
 [aCollection addObject:bar];
}
6 голосов
/ 16 февраля 2009

Линия

[aCollection addObject:bar]

это ваша проблема. Вы не можете изменить aCollection при перечислении его. Лучше было бы создать временный NSMutableArray, добавить к нему bar, а затем вызвать [aCollection addObjectsFromArray:] со своим временным массивом.

Например:

NSMutableArray *foundObjects = [NSMutableArray array];
for (NSDictionary *aDictionary in aCollection) {
    if ([[bar objectForKey:@"id"] isEqual:[aDictionary objectForKey:@"id"]])
       break;

    [foundObjects addObject:bar];
}
[aCollection addObjectsFromArray:foundObjects];
6 голосов
/ 16 февраля 2009

Сделайте копию коллекции и повторите это. После этого вы можете без проблем поменяться или добавить свою оригинальную коллекцию.

3 голосов
/ 16 февраля 2009

С Язык программирования Objective-C 2.0 , вы не можете изменять перечисляемую коллекцию:

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

2 голосов
/ 20 ноября 2010

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

for (NSDictionary *tmp in aCollection.copy) {
  if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
     break;
  [aCollection addObject:bar];
}
1 голос
/ 27 января 2012

Все остальные предложили полезные ответы, все из которых кажутся правильными.

Ваш код, однако, не делает то, что, как они думают, делает. Вероятно, он тоже не делает то, о чем вы думаете.

Вы пытаетесь добавить 'bar' в коллекцию, если первый объект, возвращаемый перечислителем, не соответствует bar.

Все думают, что вы пытаетесь добавить панель, если ее вообще нет в коллекции.

Я подозреваю, что вы взяли конструкцию Python и неправильно ее портировали.

0 голосов
/ 25 февраля 2012

решено

У меня такая же проблема при перечислении объектов coredata.

не изменять подобъект, который полагается на ARRAY, на котором работает цикл

Например, если я изменил / изменил объект во время цикла .. Это выдаст эту ошибку

 for (LoadList *objLL in ArrLoadList) {             // here Enumaration is Going on
        // here i has removed objects in ArrLoadList and reassign the ArrLoadList .. 
        // it will gives me this error 
        // So Don't change the Main Array object 
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...