この奇妙な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?!
ヒント!!
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];
}
}
もう一つのヒント!!
PoolStep は、1 つのスレッドのみがアクセスするため、sharedPool メソッドに @synchronize ブロックがないシングルトンです。(そしてパフォーマンスが必要です)