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.