我正在使用运行良好的 NSMutableSet,直到出现这个奇怪的 SIGABRT 错误:
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) 打印 (int) [theSet 计数]
$1 = 1
这怎么可能?
PS:我在多线程环境中运行..我不能保证不会同时被两个线程访问,但事实并非如此..
编辑
拜托,我真的很想知道 NSSet 怎么会以 (null) 结束,我不在乎它是如何到达那里的.. 不管我的多线程程序有多脏,我认为这不应该发生。[我仔细检查了,这个集合只能由后台工作线程访问]。
编辑
2011-07-05 17:39:55.884 应用程序 [1608:c59f] 设置计数 = 2 包含:{(
< Step: 0xc43f3e0>, < Step: 0x62f1800> )}
2011-07-05 17:39:55.886 App[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];
}
}
另一个提示!
PoolStep 是一个单例,在 sharedPool 方法中没有 @synchronize 块,因为它只能由一个线程访问。(并且需要性能)