我有一段代码,类似于以下内容:
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.'
解决这个问题的最佳方法是什么?
答案 0 :(得分: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];
}
答案 1 :(得分:6)
制作该集合的副本并进行迭代。然后,您可以毫无问题地换出或添加到原始集合。
答案 2 :(得分: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];
答案 3 :(得分:3)
从The Objective-C 2.0 Programming Language,您无法修改枚举的集合:
枚举是“安全的” - 枚举器具有变异防护,因此如果您在枚举期间尝试修改集合,则会引发异常。
答案 4 :(得分:2)
只需复制数组即可。否则你会搞乱你正在迭代的集合:
for (NSDictionary *tmp in aCollection.copy) {
if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
break;
[aCollection addObject:bar];
}
答案 5 :(得分:1)
其他人都提供了有用的答案,所有这些答案都是正确的。
然而,您的代码并没有按照他们的想法行事。它可能不会做你认为它做的事情。
如果枚举器返回的第一个对象与bar不匹配,则尝试将“bar”添加到集合中。
如果集合中根本不存在bar,那么每个人都认为你正在尝试添加吧。
我怀疑你采用了Python构造并错误移植了它。
答案 6 :(得分:0)
已解决
我在coredata对象枚举中遇到同样的问题。
不要更改依赖于运行循环的ARRAY的子对象
就像,如果我在On循环中更改/修改对象..它将给出此错误
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
}