我有两个功能:
返回一个填充在块中的数组
- (NSArray *)getArray {
NSArray *someValues = @[@0, @42, @23, @5, @8, @2013];
NSArray *filter = @[@42, @23, @5];
//replacing this NSMutableOrderedSet with a NSMutableArray
//and return just matched then, resolves the problem.
//so the exception has to do something with that set.
NSMutableOrderedSet *matched = [[NSMutableOrderedSet alloc] init];
for (id value in someValues) {
[filter enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqual:value])
[matched addObject:value];
}];
}
return [matched array];
}
和另一个从第一个方法
枚举返回的数组- (void)enumArray:(NSArray *)array {
NSEnumerator *enumerator = [array objectEnumerator];
for (id obj in enumerator) {
if ([obj isEqual:@42])
[enumerator nextObject]; // <== this line causes the error!
}
}
如果我现在做那样的话
NSArray *array = [foo getArray];
[foo enumArray:array];
我将收到一条带有以下消息的NSGenericException:
Collection&lt; __ NSOrderedSetArrayProxy:0x123456&gt;在变异的同时 被列举
地狱是变异的地方。我不懂。从该数组返回一个副本解决了问题,但我仍然没有得到它。
错误已经对NSMutableOrderedSet做了一些事情,如果我用数组替换该集合,我不会得到异常。
一些异常抛出的截图
答案 0 :(得分:3)
在更改枚举器实例时,您正在使用快速枚举。
基本上,修改一个你快速枚举的对象是一个很大的禁忌(你正在使用的for循环形式使用快速枚举)。但是,您使用[enumerator nextObject];
从枚举器访问下一个对象,但此通过从中删除当前对象来修改枚举器。所以你在一个for...in
循环中使用nextObject 来改变枚举器。
使用while循环而不是for循环快速解决这个问题,有点像这样:
- (void)enumArray:(NSArray *)array {
NSEnumerator *enumerator = [array objectEnumerator];
while ((id obj = [enumerator nextObject])) {
if ([obj isEqual:@42])
[enumerator nextObject];
}
}
这应该超过快速枚举/突变问题。注意,我完全不知道为什么你想在obj等于42的步骤中移动枚举器,但是假设在整个代码库的上下文中这是有意义的!
答案 1 :(得分:0)
基本原因是,在您通过它时,您无法编辑/修改可变数组。
所以这是两个解决方案,
1.请在变异时使用 @synchronized()
指令锁定数组。
- (void)enumArray:(NSArray *)array {
NSEnumerator *enumerator = [array objectEnumerator];
for (id obj in enumerator)
{
if ([obj isEqual:@42])
{
@synchronized(enumerator)
{
[enumerator nextObject]; // <== this line causes the error!
}
}
}
}
2.你只需要 copy
NSArray并使用它
- (void)enumArray:(NSArray *)array {
NSEnumerator *enumerator = [[array copy] objectEnumerator];
for (id obj in enumerator)
{
if ([obj isEqual:@42])
{
[enumerator nextObject]; // <== this line causes the error!
}
}
}