title: global dispatch queue blocks main thread UIs when app is launched from background (ARC enabled)
body: <p>I am using global dispatch queue to set up iCloud Coredata in my project. There is a strange problem. iCloud CoreData may take very long time to setup for the first time.</p>
  
  <p><strong>During this long period:</strong></p>
  
  <ul>
  <li><p>if the app keeps running in the forefront, and user can play with the UI
  smoothly.</p></li>
  <li><p><strong>BUT</strong> if the app goes to background, and back to forefront again, the UI
  hangs and sometimes cannot get the iCloud Core data set up properly,
  (some data not merged).</p></li>
  </ul>
  
  <p>Does the background process with dispatched queue comes to main thread when it hangs in the second scenario? </p>
  
  <p>Another possible reason: I used a separate class called "DataManager" to handle all those CoreData methods, and it is normal subclass from NSObject. 
  While Apple's sample code put all those core data stuff in AppDelegate. Might it be the reason?</p>
  
  <p>I have being struggling with the problem for three days. Please help me out. Thanks a lot.</p>
  
  <p><img src="https://i.stack.imgur.com/brw5E.png" alt="My Core Data Design"></p>
  
  <p><img src="https://i.stack.imgur.com/l8RaZ.png" alt="Instrument&gt;&gt; Scheduling for the process &quot;Launch&gt;&gt; go background&gt;&gt; come forefront&quot;"></p>
  
  <pre><code>- (NSPersistentStoreCoordinator *)cloud_persistentStoreCoordinator {
  
  if (_cloud_persistentStoreCoordinator != nil) {
      return _cloud_persistentStoreCoordinator;
  }
  
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:UBIQUITY_CONTAINER_URL];
  
  if (!cloudURL) {
      self.iCloudReady=NO;
      self.iCloudCoreDataReady=YES;
      DEBUGLog
      return nil;
  }
  self.iCloudReady=YES;
  _cloud_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
  // prep the store path and bundle stuff here since NSBundle isn't totally thread safe
  NSPersistentStoreCoordinator* psc = _cloud_persistentStoreCoordinator;
  NSURL *storeUrl = [[self applicationLibraryDirectory] URLByAppendingPathComponent:@"cloud_accounts.sqlite"];
  
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  
  NSURL* coreDataCloudContentURL = [cloudURL URLByAppendingPathComponent:@"accounts_v1"];
  //  The API to turn on Core Data iCloud support here.
  NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@"com.moremore.cloudapp.keys", NSPersistentStoreUbiquitousContentNameKey, coreDataCloudContentURL, NSPersistentStoreUbiquitousContentURLKey, [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
  
  NSError *error = nil;
  [psc lock];
  if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&amp;error]) {
  
      /*
  
       Replace this implementation with code to handle the error appropriately.
  
       abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
  
       Typical reasons for an error here include:
       * The persistent store is not accessible
       * The schema for the persistent store is incompatible with current managed object model
       Check the error message to determine what the actual problem was.
       */
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
  } 
      [psc unlock];
  
  
      // tell the UI on the main thread we finally added the store and then
      // post a custom notification to make your views do whatever they need to such as tell their
      // NSFetchedResultsController to -performFetch again now there is a real store
  
      dispatch_async(dispatch_get_main_queue(), ^{
          //user userDefaults to mark this will only be run once
          NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
          if ([userDefault objectForKey:@"oldCloudAccountsmoved"]==nil) {
              AppDelegate * appdelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
              [appdelegate moveOld_Cloud_DatabasetoCoreData];  
              NSString * confirm=@"YES";
              [userDefault setObject:confirm forKey:@"oldCloudAccountsmoved"];
              [userDefault synchronize];
          }
  
          NSLog(@"asynchronously added persistent store!");
          [[NSNotificationCenter defaultCenter] postNotificationName:@"coreData_iCloud_Ready" object:self userInfo:nil];
      });
  });
  
  
  return _cloud_persistentStoreCoordinator;
  }
  </code></pre>