0

我正在使用运行良好的 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?!

暗示!!

查看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 是一个单例,在 sharedPool 方法中没有 @synchronize 块,因为它只能由一个线程访问。(并且需要性能)

4

1 回答 1

2

您是否尝试将它和任何其他使用 theSet 的代码包装在同步(theSet)块中,线程问题可以解释您的问题。也许 null 是由一些中间状态引起的。

于 2011-07-05T14:40:32.907 回答