Note that there are some explanatory texts on larger screens.

plurals
  1. POManagedObjectContexts with threads (dispatch queues) gets into a deadlock on iOS7
    primarykey
    data
    text
    <p>I know there are many threads about NSManagedObjectContexts and threads but my problem seems to be only specific to iOS7. (Or at least not visible in OS6)</p> <p>I have an app that makes use of dispatch_queue_ and runs multiple threads to fetch data from the server and update the UI. The app was working fine on iOS6 but on iOS7 it seems to get into deadlocks(mutex wait). See below the stack trace -</p> <p><img src="https://i.stack.imgur.com/NpZOz.png" alt="enter image description here"></p> <p>The "wait" happens in different methods usually when executing a fetch request and saving a (different) context. The commit Method is as follows :</p> <pre><code>-(void)commit:(BOOL) shouldUndoIfError forMoc:(NSManagedObjectContext*)moc { @try { // shouldUndoIfError = NO; // get the moc for this thread NSManagedObjectContext *moc = [self safeManagedObjectContext]; NSThread *thread = [NSThread currentThread]; NSLog(@"got login"); if ([thread isMainThread] == NO) { // only observe notifications other than the main thread [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc]; NSLog(@"not main thread"); } NSError *error; if (![moc save:&amp;error]) { // fail NSLog(@"ERROR: SAVE OPERATION FAILED %@", error); if(shouldUndoIfError) { [moc undo]; } } if ([thread isMainThread] == NO) { [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:moc]; } } @catch (NSException *exception) { NSLog(@"Store commit - %@",exception); NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"name",@"store commit",@"exception", exception.description, nil]; [Flurry logEvent:@"MyException" withParameters:dictionary timed:YES]; } @finally { NSLog(@"Store saved"); } } </code></pre> <p>How I'm creating new contexts for each thread :</p> <pre><code>-(NSManagedObjectContext *)safeManagedObjectContext { @try { if(self.managedObjectContexts == nil){ NSMutableDictionary *_dict = [[NSMutableDictionary alloc]init]; self.managedObjectContexts = _dict; [_dict release]; _dict = nil; } NSManagedObjectContext *moc = self.managedObjectContext; NSThread *thread = [NSThread currentThread]; if ([thread isMainThread]) { return moc; } // a key to cache the context for the given thread NSString *threadKey = [NSString stringWithFormat:@"%p", thread]; if ( [self.managedObjectContexts valueForKey:threadKey] == nil) { // create a context for this thread NSManagedObjectContext *threadContext = [[[NSManagedObjectContext alloc] init] retain]; [threadContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; [threadContext setPersistentStoreCoordinator:[moc persistentStoreCoordinator]]; [threadContext setUndoManager:nil]; // cache the context for this thread [self.managedObjectContexts setObject:threadContext forKey:threadKey]; NSLog(@"added a context to dictionary, length is %d",[self.managedObjectContexts count]); } return [self.managedObjectContexts objectForKey:threadKey]; } @catch (NSException *exception) { // } @finally { // } } </code></pre> <p>What I have so far :</p> <ul> <li>One Persistent Store coordinator.</li> <li>Each New thread has its own Managed Object Context.</li> </ul> <p>Strange part is that the same code worked fine on OS6 but not on OS7. I am still using the xcode4.6.3 to compile the code. Most of the code works on this principle, I run a thread, fetch data, commit it and then post a notification. Could the freeze/deadlock be because the notification gets posted and my UI elements fetch the data before the save(&amp;merge) are reflected? Anything else that I'm missing ?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload