2011-07-05 48 views
0

現在用的是的NSMutableSet是偉大的工作,直到這個奇怪的SIGABRT錯誤彈出:NSMutableSet count = 1,但該對象爲空?

2011-07-05 17:01:00.249大媽[1497:CD57] *終止應用程序由於未捕獲異常 'NSInvalidArgumentException',原因是: ' - [__ NSCFSet的removeObject:]:嘗試刪除零'

好吧,我不能刪除零,但這裏是我的代碼:

id item = nil; 
if ([theSet count] == 0) { // This equals 1 !! 
    item = [[[self getClass] alloc] init]; 
} else { 
    item = [[theSet anyObject] retain]; //this returns nil !! 
    [theSet removeObject:item]; // ERROR !! 
} 

用GDB控制檯,我發現theSet看起來像這樣:

(GDB)PO theSet

{(

(null) 

)}

(GDB)打印(INT)[ theSet count]

$ 1 = 1

這怎麼可能?

PS:我在一個多線程的環境中運行。我不能保證在沒有被兩個線程同時訪問,但它不應該是這樣..

編輯

請,我真的想知道如何能NSSet中結束了(空),我不關心它是如何到達那裏。無論我的多線程程序有多髒,這不應該」我想,不會發生。 [和我加倍檢查,這個集合只能被後臺工作線程訪問]。

EDIT

2011-07-05 17:39:55.884應用[1608:c59f]設置計數= 2 包含:{(

< Step: 0xc43f3e0>, 
< Step: 0x62f1800>)} 

2011-07-05 17:39:55.886 應用[1608:c59f]設置計數= 9包含:{(

>  < Step: 0x62eece0>, 
>  < Step: 0xc490660>, 
>  < Step: 0xcb597d0>, 
>  < Step: 0x65a4f60>, 
>  < Step: 0xc43f4b0>, 
>  < Step: 0xc43f3e0>, 
>  < Step: 0x65c8f60>, 
>  < Step: 0xc499230>, 
>  (null))} //null appeared?! 

提示!!

檢查出Step dealloc方法(XD):

-(void)dealloc{ 
    if (![[PoolStep sharedPool] purgeFlag]) { 
     [[PoolStep sharedPool] doneWithItem:self]; //put it in the object pool for reuse.. 
    } else { 
     NSLog(@"=== STEP ====> [ %d ]", --_counter); 
     [children release]; 
     [super dealloc]; 
    } 
} 

另一個HINT !!

PoolStep是sharedPool方法中沒有@synchronize塊的單例,因爲它只被一個線程訪問。(並且需要性能)

+0

[theSet count] returned 1 ..這就是讓我困惑的事......更不用說gdb輸出 – Mazyod

回答

2

您是否嘗試過使用同步(theSet)塊中的Set函數包裝它,以及其他任何使用Set的代碼,線程問題可以解釋您的問題。也許null是由一些中間狀態引起的。

+0

問題是我每2ms訪問一次(大致)一次(模擬器上)。性能是我的頭號優先事項。 – Mazyod

+0

您應該嘗試在調試版本中使用。在這個實驗之後,您將知道您的問題是否是確定性問題或線程問題。 2ms有足夠的時間來取鎖。 –

+0

問題是,它是隨機的..我只玩了10分鐘的遊戲,什麼也沒有發生。問題是:「NSSet如何包含null?」 – Mazyod