2012-04-24 59 views
1

我必须每隔一段时间删除一个数组的对象,当我这样做的时候出现这个错误。CALayerArray在枚举时发生了变化

收集< CALayerArray:0xc4f3b20>物而被枚举突变

在此方法,这是该数组的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个元素,所以它可能需要一些时间去通过所有这些,但我设置队列,不知道还有什么我能做的。

任何想法?

谢谢。

+0

不检查队列是否为当前队列。一个创建的队列可以有一个目标队列,这意味着一个队列可以将工作集中到另一个队列上,将其工作到另一个队列等。dispatch_get_current_queue不能返回每个涉及的队列。只要总是派遣你的工作,并且相信GCD在可能和安全的情况下将该工作内联。 – Jesper 2012-04-24 08:27:58

+0

我应该创建一个新的队列吗? – subharb 2012-04-24 08:33:24

+0

不,只是总是调用dispatch_async或dispatch_sync来告诉GCD在队列中执行某些操作。无论您目前是否在队列的线程中都无关紧要,因为您应该避免dispatch_sync,除非您能*保证*您不在队列的线程中。 – Jesper 2012-04-24 08:38:13

回答

4

此代码:

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]; 
+0

谢谢,这工作完美,无需线程。 – subharb 2012-04-24 09:25:43

相关问题