I'm unable to get my NSFetchedResultsControllerDelegate
methods called when setting the NSFetchedResultsControllerDelegate
up with a concurrencyType
value of privateQueueConcurrencyType
.
Consider this example:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Note> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Note> = Note.fetchRequest()
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.coreDataManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
Where the coreDataManager
class has this:
private(set) lazy var managedObjectContext: NSManagedObjectContext = {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
If I call fetchedResultsController.managedObjectContext.delete(note)
and then save, the controller:didChangeObject:atIndexPath:forChangeType:newIndexPath
method is called and I can respond to the deletion of the note object.
If I change the code above to be:
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Note> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Note> = Note.fetchRequest()
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let managedObjectContext = NSManagedObjectContext(concurrencyType: .concurrencyType`)
managedObjectContext.persistentStoreCoordinator = self.coreDataManager.managedObjectContext.persistentStoreCoordinator
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
Which specifically changes the managed object context 'usage' from using self.coreDataManager.managedObjectContext
to a new version that should work on a background thread, the delegate methods are never called when items are deleted.
viewDidLoad
self.coreDataController.managedObjectContext
fetchedResultsController
method to use a different NSManagedObjectContext
So my main question is - how do I get the NSFetchedResultsControllerDelegate
methods to be called when using this type of NSManagedObjectContext
?
The fetchedResultsController
is monitoring the context that you just created and that context is not processing updates. If you want this context to change you have to set automaticallyMergesChangesFromParent = true
for the context.
As John told NSFetchedResultsController is monitoring only associated managed context like
lazy var fetchedResultsController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in let request = NSFetchRequest<NSFetchRequestResult>.init(entityName: "Repository") let descriptors = [NSSortDescriptor.init(key: "name", ascending: true), NSSortDescriptor.init(key: "name", ascending: true)] request.sortDescriptors = descriptors let resultsController = NSFetchedResultsController.init(fetchRequest: request, managedObjectContext: CoreDataManager.shared.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil) resultsController.delegate = self return resultsController }()
Inherit your .mainQueueConcurrencyType from .privateQueueConcurrencyType like below code
lazy var managedObjectContext: NSManagedObjectContext = { let context = NSManagedObjectContext.init(concurrencyType: .mainQueueConcurrencyType) context.parent = self.privateQueueManagedObjectContext context.automaticallyMergesChangesFromParent = true return context }() lazy var privateQueueManagedObjectContext: NSManagedObjectContext = { let context = NSManagedObjectContext.init(concurrencyType: .privateQueueConcurrencyType) context.persistentStoreCoordinator = self.persistentStoreCoordinator return context }()
Dont forget to add context.automaticallyMergesChangesFromParent = true in your maincontext to notify background operations on privateQue context.
I hope this will work
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.