【问题标题】:CALayerArray was mutated while being enumeratedCALayerArray 在枚举时发生了突变
【发布时间】:2012-05-04 20:53:58
【问题描述】:

我必须时不时地删除一个数组的对象,当我这样做时,我得到了这个错误。

集合 在枚举时发生了变异

这个方法出现错误,是Array的accesor:

- (NSArray *)occupantsArray
{
    if (dispatch_get_current_queue() == moduleQueue)
    {
        return occupantsArray;
    }
    else
    {
        __block NSArray *result;

        dispatch_sync(moduleQueue, ^{ //ON THIS LINE
            result = [occupantsArray copy];
        });

        return [result autorelease];
    }
}

如您所见,我注意不返回原始数组而是返回副本,但它仍然崩溃。

我删除数组元素的方法也是这个。

- (void)eraseJIDFromArray:(NSString*)jid{

    dispatch_block_t block = ^{
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        int i = 0;
        for(NSString *jidAct in occupantsArray){
            if([jidAct isEqualToString:jid]){
                [occupantsArray removeObjectAtIndex:i];
            }
            i++;
        }
        [pool drain];
    };

    if (dispatch_get_current_queue() == moduleQueue)
        block();
    else
        dispatch_async(moduleQueue, block);



}

数组最多可以有 200 个元素,因此可能需要一些时间来遍历所有元素,但我正在设置队列,不知道还能做什么。

有什么想法吗?

谢谢。

【问题讨论】:

  • 不检查队列是否为当前队列。创建的队列可以有一个目标队列,这意味着一个队列可以将工作集中到另一个队列,将工作集中到另一个队列,等等。dispatch_get_current_queue 不能返回每个涉及的队列。只要始终调度您的工作,并相信 GCD 会在可能且安全的情况下内联该工作。
  • 我应该创建一个新队列吗?
  • 不,只是总是调用 dispatch_async 或 dispatch_sync 来告诉 GCD 在队列中做某事。无论您当前是否在队列的线程上都没有关系,只要您应该避免 dispatch_sync,除非您可以保证您不在队列的线程上。

标签: objective-c nsarray dispatch


【解决方案1】:

这段代码:

for(NSString *jidAct in occupantsArray){
    if([jidAct isEqualToString:jid]){
        [occupantsArray removeObjectAtIndex:i];
    }
    i++;
}

可能导致您的问题。枚举数组时不应该删除元素。避免这种情况的方法是使用 NSMutableIndexSet:

NSMutableIndexSet *indexes = [NSMutableIndexSet set]; // assuming NSInteger i;
for(NSString *jidAct in occupantsArray){
    if([jidAct isEqualToString:jid]){
        [indexes addIndex:i];
    }
    i++;
}
[occupantsArray removeObjectsAtIndexes:indexes];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2012-09-21
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多