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!
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.