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.
Would
NSSet* collectibleCopy = [NSSet setWithSet:_collectibles]
work for you?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With