4

私には2つの機能があります:

ブロックに埋められた配列を返すもの

- (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 を取得します。

コレクション <__NSOrderedSetArrayProxy: 0x123456> が列挙中に変更されました

一体どこが変異したのか。理解できません。その配列からコピーを返すと問題は解決しますが、まだわかりません。

NSMutableOrderedSet でエラーが発生しました。セットを配列に置き換えても、例外は発生しません。

スローされた例外のスクリーンショット

すべての例外ブレークポイント クラッシュ

4

2 に答える 2

0

基本的な理由は、変更可能な配列を実行中に編集/変更できないことです。

ここに2つの解決策があります、

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.NSArraycopyを実行して使用するだけです

- (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!
        }
    }
}
于 2013-07-30T05:46:31.577 に答える