Note that there are some explanatory texts on larger screens.

plurals
  1. POiOS CoreData Background Thread Fetching in cellForRowAtIndexPath
    primarykey
    data
    text
    <p>I have a tableview in my app that contains a NSFetchedResultsController to load in some CoreData objects.</p> <p>As the table builds in <code>cellForRowAtIndexPath:</code>, for each cell I must do a fetch to get some other info from another object. </p> <p>The table is filled with UserTasks, and I must get some info from a UserSite (UserTask contains a siteID attribute)</p> <p>I am getting the UserSite info in a background thread, and using a temporary context. It works fine, but it still wants to lag the UI a bit when scrolling.</p> <pre><code> Site *site = [_scannedSites objectForKey:task.siteID]; if(!site) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ AppDelegate *ad = [AppDelegate sharedAppDelegate]; NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]; temporaryContext.persistentStoreCoordinator = ad.persistentStoreCoordinator; Site *site2 = [task getSiteWithContext:temporaryContext]; if(site2) { [ad.managedObjectContext performBlock:^{ Site *mainContextObject = (Site *)[ad.managedObjectContext objectWithID:site2.objectID]; [_scannedSites mainContextObject forKey:task.siteID]; }]; dispatch_async(dispatch_get_main_queue(), ^{ Site *newSite = [_scannedSites objectForKey:task.siteID]; cell.lblCustName.text = newSite.siteName; cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", newSite.siteAddressLine1, newSite.siteCity, newSite.siteState]; cell.lblPhone.text = [self formatPhoneNum:newSite.phone]; }); } else { dispatch_async(dispatch_get_main_queue(), ^{ cell.lblCustName.text = @""; cell.lblAddr.text = @""; cell.lblPhone.text = @""; }); } }); } else { cell.lblCustName.text = site.siteName; cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", site.siteAddressLine1, site.siteCity, site.siteState]; cell.lblPhone.text = [self formatPhoneNum:site.phone]; } </code></pre> <p>As you can see, if you dont already have the UserSite info for a task in <code>_scannedSites</code>, a background thread gets kicked off which gets the UserSite for that task, stores it, and then on the main thread fills in the details.</p> <p>Like I said there is a pretty annoying lag when scrolling... which I hoped to avoid by doing the work in the background.</p> <p>Am I going about this the wrong way?</p> <p>Thanks, any advice is appreciated.</p> <hr> <p><strong>EDIT</strong> I created a relationship in CoreData and I am now using that in <code>cellForRowAtIndexPath</code>. If it does not exist yet, I create it. This is working much better.</p> <pre><code> Site *site = task.site; if(!site) { AppDelegate *ad = [AppDelegate sharedAppDelegate]; NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; temporaryContext.persistentStoreCoordinator = ad.persistentStoreCoordinator; [temporaryContext performBlock:^{ Site *tempContextSite = [task getSiteWithContext:temporaryContext]; [ad.managedObjectContext performBlock:^{ Site *mainManagedObject = (Site *)[ad.managedObjectContext objectWithID:tempContextSite.objectID]; task.site = mainManagedObject; NSError *error; if (![temporaryContext save:&amp;error]) { } [ad.managedObjectContext performBlock:^{ NSError *e = nil; if (![ad.managedObjectContext save:&amp;e]) { } dispatch_async(dispatch_get_main_queue(), ^{ cell.lblCustName.text = mainManagedObject.siteName; cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", mainManagedObject.siteAddressLine1, mainManagedObject.siteCity, mainManagedObject.siteState]; cell.lblPhone.text = [self formatPhoneNum:mainManagedObject.phone]; }); }]; }]; }]; } else { cell.lblCustName.text = site.siteName; cell.lblAddr.text = [NSString stringWithFormat:@"%@ %@, %@", site.siteAddressLine1, site.siteCity, site.siteState]; cell.lblPhone.text = [self formatPhoneNum:site.phone]; } </code></pre>
    singulars
    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