I have a singleton data manager object that manages the connection to a web service, processes the data and then updates a mutable dictionary with the objects. All requests for this dictionary are via this singleton instance that I have created. Now and again I will get conflicts as I am obviously editing a mutable object from many threads and so get the occasional EXC_BAD_ACCESS.
I could implement @synchronized methods or use NSLock but as I am already making extensive use of Grand Central Dispatch I was wondering if there is anything I can do there by forcing them all down one thread synchronously? I also am not sure if the above methods would work and how they would be implemented.
Example code below. The exception can occur in the getObjectArray method as I could be adding to it/updating sub object/deleting in the translateToObjectFromDict method.
NSMutableDictionary *staticDictionary;
-(NSArray *)getObjectArray{
NSArray *returnArray = [[[NSArray alloc]init]autorelease];
returnArray = [self.staticDictionary allValues];
return returnArray;
}
-(void)translateToObjectFromDict:(NSDictionary *)sourceDictionary{
dispatch_group_t taskGroup = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_group_async(taskGroup,queue,^(){
for (id key in sourceDictionary) {
NSDictionary *subDictionary = [sourceDictionary objectForKey:key];
for (id key in subDictionary) {
NSArray *theObjData = [subDictionary objectForKey:key];
if ([theObjData count] == 12) {
theObj *temptheObj = [[PINKtheObj alloc] initWith......
NSString *unihex = temptheObj.unihex;
if ([self.staticDictionary objectForKey:unihex]){
PINKtheObj *localtheObj = [self.staticDictionary objectForKey:unihex];
if (temptheObj.time > localtheObj.time) {
[localtheObj updatetheObjWith.......
[temptheObj release];
}else{
[self.staticDictionary setObject:temptheObj forKey:unihex];
}
}
}
}
});
dispatch_group_notify(taskGroup, queue, ^{
NSDictionary *getMainDict = [self.mainDictionary objectForKey:@"theObjs"];
for (id key in self.staticDictionary) {
if (![getMainDict objectForKey:key]){
[self.removeArray addObject:[self.staticDictionary objectForKey:key]];
}
}
[[NSNotificationCenter defaultCenter]postNotificationName:@"updated" object:nil];
});
dispatch_release(taskGroup);
}
I think you should supply all your calls (
objectForKey:,setObject:ForKey:, etc.) to yourstaticDictionaryin your own serial queue. Create it when singleton initializes and use everywhere.In your header file create ivar.
In .m file just add to
initWhen you want to access or put data into dictionary just make
You can use
dispatch_syncif you want your task to wait for returned value.