TL;DR; There is no good reason to use a context on the main queue.
can use NSFetchedResultsController to fetch data in background
Absolutely. NSFetchedResultsController
can be used with a private queue context. It is, in fact, quite happy and performant when doing so. There is a bug that prevents NSFetchedResultsController
from using it's cache when it's using a private queue, but the cache does not win you as much as it did in iOS 3.0. Set a cacheName
of nil and you will be fine.
1.
Create a context with NSPrivateQueueConcurrencyType
. Preferably not the one you use for IO.
2.
Create the fetched results controller with that context, and a cache name of nil.
3.
Perform your initial fetch from within a performBlock:
block:
[[[self fetchedResultsController] managedObjectContext] performBlock:^{
NSError *fetchError = nil;
if (![self fetchedResultsController] performFetch:&error]){
/// handle the error. Don't just log it.
} else {
// Update the view from the main queue.
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[tableView reloadData];
}];
}
}];
4.
All of your delegate callbacks will now happen from the context's queue. If you are using them to update views, do so by dispatching to the main queue like you see above.
5.
...
6.
Profit!
You can read more about this here.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…