Crash in NSDictionaryController -addObject:

Consider the following code fragments:

@property (readonly) NSDictionaryController *loggedConfigsController;
	_loggedConfigs												= NSMutableDictionary.dictionary;
	_loggedConfigsController									= [NSDictionaryController.alloc initWithContent:self.loggedConfigs];
	_loggedConfigsController.sortDescriptors					= @[[NSSortDescriptor sortDescriptorWithKey:@"value" ascending:YES]];
	_loggedConfigsController.preservesSelection					= YES;
	_loggedConfigsController.avoidsEmptySelection				= YES;
	_loggedConfigsController.selectsInsertedObjects				= NO;
	_loggedConfigsController.automaticallyRearrangesObjects		= YES;
- (void)logEventWithTitle:(NSString *)title ident:(p_ident_t)ident {
    // called from main queue and dispatch queues
		NSString *identString	= [self identStringForIdent:ident];
		NSNumber *dictIdent 	= self.loggedConfigs[identString];
		if (dictIdent == nil) {
			NSDictionaryControllerKeyValuePair *c = self.loggedConfigsController.newObject;
			c.key	= identString;
			c.value	= title;
			[self.loggedConfigsController addObject:c];// crash 
		}
}

Crash log:

Thread 4 Crashed::  Dispatch queue: Pinger #9
0   libobjc.A.dylib               	    0x7ff81bb7fcc3 objc_retain + 35
1   AppKit                        	    0x7ff81f18d831 -[NSArrayController _setObjects:] + 49
2   AppKit                        	    0x7ff81f18e502 -[NSArrayController _arrangeObjectsWithSelectedObjects:avoidsEmptySelection:operationsMask:useBasis:] + 365

Does anyone know why -addObject: fails?

Any help is appreciated. Thanks in advance!

Accepted Reply

I was able to reproduce the problem in the debugger:

Thread 68: "Cannot remove an observer <NSDictionaryController 0x7fc4f530e290> for the key path \"value\" from <_NSDictionaryControllerKeyValuePair 0x60000093e2b0> because it is not registered as an observer."

The problems were

a) I use NSString as the value, but check for an NSNumber, hence it should be

		NSString *dictIdent 	= self.loggedConfigs[identString];

but that didn't cause the actual crash

b) The method was called from multiple dispatch queues at the same time, causing a mutating while enumerating crash.

Replies

I was able to reproduce the problem in the debugger:

Thread 68: "Cannot remove an observer <NSDictionaryController 0x7fc4f530e290> for the key path \"value\" from <_NSDictionaryControllerKeyValuePair 0x60000093e2b0> because it is not registered as an observer."

The problems were

a) I use NSString as the value, but check for an NSNumber, hence it should be

		NSString *dictIdent 	= self.loggedConfigs[identString];

but that didn't cause the actual crash

b) The method was called from multiple dispatch queues at the same time, causing a mutating while enumerating crash.