奇怪的NSSet复制崩溃

我有一个包含NSSet的类。 这个对象被称为_collectibles ,在一个方法中,我做了一个副本,以便做一些处理,如:

NSSet* collectibleCopy = [_collectibles copy];

在实践中,我看到这个消息经常崩溃:

[__NSPlaceholderSet initWithObjects:count:]: attempt to insert nil object from objects

我通过将上面的代码更改为:

NSMutableSet* collectibleCopy = [[NSMutableSet alloc] initWithCapacity: [_collectibles count]];
for ( id thing in _collectibles ) {
    [collectibleCopy addObject: thing];
}

现在我再也不能再现这样的崩溃了。 我打赌[copy]效率更高,我宁愿使用它,但我无法弄清楚为什么它是完全不可靠的!

更新:虽然完整的上下文需要大量的解释,但我解决这个问题的关键是,a,代码是这样调用的:

NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock: ^{
   [thing doStuff];
}];

[operationQueue addOperation: operation];

我的意思是,基本上是通过减慢一些事情,使用2个线程运行2个线程来捕获应用程序,从而初始化一个队列:

operationQueue.maxConcurrentOperationCount = 1;

我认为不可能。 线索是第二个线程在[NSAutoreleasePool drain]中,这让我了解到NSOperationQueue可以在任何时候/无论它想要什么时候执行autorelease。


NSSet* collectibleCopy = [NSSet setWithSet:_collectibles] 

为你工作?


好吧,真的很想知道这件事。

这里的诀窍是这个操作是在一个异步NSOperationQueue上执行的。 TIL表示NSOperationQueues拥有AutoreleasePools,但是他们会根据GCD的判断将其耗尽。 在这种情况下,来自先前操作的池正在另一个线程上同时耗尽,导致相当不透明的并发修改问题。

解:

@autoreleasepool在代码被调用的块内部。 这会导致排水作为块的一部分发生,而不是异步发生,并且我的比赛状况消失。

链接地址: http://www.djcxy.com/p/71593.html

上一篇: Bizarre NSSet copying crash

下一篇: How to pass parameter to Microsoft Sync 2.1 generated Stored procedures