2012-04-24 58 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

相關問題