Objective-C 2.0和Fast Enumeration抛出异常

Coo*_*coa 5 cocoa cocoa-touch enumeration objective-c

我有一个代码块,类似于以下内容:

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

这在技术上是Objective-C 2.0中的一个例外吗?看起来你不能用快速枚举变异集合.这是错误的结果:

*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <NSCFArray: 0x396000> was mutated while being enumerated.'
Run Code Online (Sandbox Code Playgroud)

解决这个问题的最佳方法是什么?

And*_*ant 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];
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*yne 6

制作该集合的副本并进行迭代.然后您可以更换或添加到原始集合而不会出现问题.


Ale*_*lex 6

这条线

[aCollection addObject:bar]
Run Code Online (Sandbox Code Playgroud)

是你的问题.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];
Run Code Online (Sandbox Code Playgroud)

  • 当你可以迭代`[aCollection copy]时,为什么还要费心去做所有这些? (7认同)

mou*_*iel 3

从Objective-C 2.0 编程语言开始,您无法修改正在枚举的集合:

\n\n
\n

枚举为 \xe2\x80\x9csafe\xe2\x80\x9d\xe2\x80\x94 枚举器具有突变防护,因此如果您尝试在枚举期间修改集合,则会引发异常。

\n
\n