I have code accessing and setting an NSDictionary many times across multiple threads, like so:
- (BOOL)flagForItem:(NSNumber*)itemID
{
if(itemID) {
return [[_itemFlagDict objectForKey:itemID] boolValue]
}
return NO;
}
and:
- (void)setFlagForItem:(NSNumber*)itemID
{
if(itemID) {
NSMutableDictionary *copy = [_itemFlagDict mutableCopy];
[copy setObject:[NSNumber numberWithBool:YES] forKey:itemID];
_itemFlagDict = [NSDictionary dictionaryWithDictionary:copy];
}
}
In the set method, I originally had a NSMutableDictionary - this was changed to the pattern you see now because, doh, NSMutableDictionary isn't threadsafe. My reasoning was to perform the mutation in a copy, and then reassign the _itemFlagDict
to capture the update.
However, occasionally a EXC_BAD_ACCESS
crash still occurs when accessing the _itemFlagDict
, leading me to believe that the dictionary is reassigned WHILE the accessing the objectForKey:itemID
.
One other approach I tried was to use @synchronized(_itemFlagDict)
on both the accessor and the setter methods. While this fixed the issue, this code is performance sensitive and synchronizing the access/assignment caused too much performance degradation.
So my question is, are there other patterns/methods I can use to avoid this bad access while not compromising performance? If prioritization matters, the execution (and not necessarily iron-clad accuracy) of the accessor method is most important.
Note: i'm working with iOS 4 and above