0

この奇妙なSIGABRTエラーがポップアップするまで、うまく機能しているNSMutableSetを使用しています:

2011-07-05 17:01:00.249 Dama[1497:cd57] *キャッチされない例外 'NSInvalidArgumentException' が原因でアプリを終了しています。理由: '-[__NSCFSet removeObject:]: nil を削除しようとしています'

わかりました、nil を削除することはできませんが、これが私のコードです:

    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) print (int) [theSet カウント]

$1 = 1

これはどのように可能ですか?

PS: マルチスレッド環境で実行しています.. 2 つのスレッドが同時にアクセスしていないとは約束できませんが、そうであってはなりません..

編集

どうやって NSSet が (null) になるのか本当に知りたいのですが、どうやってそこにたどり着いたのか気にしません.. 私のマルチスレッドプログラムがどんなに汚れていても、これは起こるべきではないと思います. [そして再確認しましたが、このセットはバックグラウンド ワーカー スレッドによってのみアクセスされます]。

編集

2011-07-05 17:39:55.884 App[1608:c59f] セット数 = 2 内容: {(

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

2011-07-05 17:39:55.886 App[1608:c59f] Set count = 9 内容: {(

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

ヒント!!

Stepdealloc メソッド (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];
    }
}

もう一つのヒント!!

PoolStep は、1 つのスレッドのみがアクセスするため、sharedPool メソッドに @synchronize ブロックがないシングルトンです。(そしてパフォーマンスが必要です)

4

1 に答える 1

2

それと、theSet を使用する他のコードを同期 (theSet) ブロックでラップしようとしたことがありますか?スレッド化の問題が問題を説明している可能性があります。おそらく、ヌルは何らかの中間状態によって引き起こされます。

于 2011-07-05T14:40:32.907 に答える