草庐IT

ios - 在没有突变的情况下得到 "NSOrderedSetArrayProxy was mutated while being enumerated"错误

coder 2023-09-28 原文

我有两个功能:

一个返回一个填充在 block 中的数组

- (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 <__NSOrderedSetArrayProxy: 0x123456> was mutated while being enumerated

这到底是哪里发生了变异。我不明白。从该数组返回一个副本解决了问题,但我仍然不明白。

错误与 NSMutableOrderedSet 相关,如果我用数组替换集合,我不会得到异常。

一些截图,异常抛出

最佳答案

您在更改枚举器实例时正在使用快速枚举

基本上,修改您快速枚举的对象是一个很大的禁忌(您正在使用的 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 时将枚举器移动到一个步骤上,但我假设在整个代码库的上下文中这是有道理的!

关于ios - 在没有突变的情况下得到 "NSOrderedSetArrayProxy was mutated while being enumerated"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17852523/

有关ios - 在没有突变的情况下得到 "NSOrderedSetArrayProxy was mutated while being enumerated"错误的更多相关文章

随机推荐