Objective-C 2.0 和快速枚举抛出异常

5

我有一段类似于以下代码的代码块:

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

解决这个问题的方法不是在枚举数组时改变它(例如添加一个对象) :)

问题在于通过添加/删除元素修改数组可能会导致枚举值变为无效,因此这是一个问题。

在您的情况下,最简单的解决方法是修复代码中的错误。您的代码正在对数组中的每个项目执行“else add”子句,我相信这不是您想要的。

尝试这个:

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

这条线

[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];

7
为什么要这么麻烦,当你可以对 [aCollection copy] 进行迭代时? - Dan Rosenstark

6

复制集合并遍历它。然后,您可以更改或添加原始集合而不会出现问题。


3

根据《Objective-C 2.0编程语言》,在枚举时不能修改正在被枚举的集合:

枚举是“安全”的——枚举器具有突变保护功能,因此如果您在枚举期间尝试修改集合,则会引发异常。


2
只需复制数组即可。否则你就会干扰正在迭代的集合:
for (NSDictionary *tmp in aCollection.copy) {
  if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
     break;
  [aCollection addObject:bar];
}

1

其他人都提供了有用的答案,这些答案似乎都是正确的。

然而,你的代码并没有做到他们认为它应该做的事情。 它可能也不会做你认为它应该做的事情。

你尝试将“bar”添加到集合中,如果枚举器返回的第一个对象与bar不匹配。

每个人都认为你是在尝试添加bar,如果它在集合中根本不存在。

我怀疑你使用了Python的语法结构,并且转移时出现了错误。


这是一条注释而不是问题。不过你可能是对的 :) - Dan Rosenstark

0

已解决

我在遍历CoreData对象时遇到了同样的问题。

不要更改依赖于正在运行循环的数组中的子对象。

例如,如果我在循环中更改/修改对象,则会出现此错误。

 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 
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接