Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bizarre NSSet copying crash

Tags:

objective-c

I have a class that contains an NSSet. That object is called _collectibles, and in a method, I make a copy of that set in order to do some processing, something like:

NSSet* collectibleCopy = [_collectibles copy];

In practice, I see this regularly crash with this message:

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

I've resolved the issue by changing the above code to:

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

And now I can no longer reproduce any such crash. I'm betting [copy] is more efficient, and I'd rather use it, but I can't figure out why it's completely wonky!

Update: while full context would take a ton of explanation, the keys to me solving this were that, a, the code was invoked this way:

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

[operationQueue addOperation: operation];

And that I was, basically by making a bunch of things slower, catch the app with 2 threads running 2 threads for a queue initialized thusly:

operationQueue.maxConcurrentOperationCount = 1;

Which I thought impossible. The clue was that the second thread was in [NSAutoreleasePool drain], which led me to learn that NSOperationQueue can do autorelease stuff whenever/however it wants.

like image 372
GoldenBoy Avatar asked May 24 '13 14:05

GoldenBoy


1 Answers

Would

NSSet* collectibleCopy = [NSSet setWithSet:_collectibles] 

work for you?

like image 168
savner Avatar answered Oct 20 '22 20:10

savner