'Why automaticallyMergesChangesFromParent work for NSFetchedResultsController, but not the manual NotificationCenter observing?

Currently, there are 2 NSManagedObjectContext used in our app

  1. CoreDataStack.INSTANCE.persistentContainer.viewContext
  2. CoreDataStack.INSTANCE.backgroundContext

class CoreDataStack {
    static let INSTANCE = CoreDataStack()
    
    private init() {
    }
    
    private(set) lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "wenote")
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // This is a serious fatal error. We will just simply terminate the app, rather than using error_log.
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        
        // So that when backgroundContext write to persistent store, container.viewContext will retrieve update from
        // persistent store.
        container.viewContext.automaticallyMergesChangesFromParent = true
        
        return container
    }()
    
    private(set) lazy var backgroundContext: NSManagedObjectContext = {
        let backgroundContext = persistentContainer.newBackgroundContext()

        // Similar behavior as Android's Room OnConflictStrategy.REPLACE
        // Old data will be overwritten by new data if index conflicts happen.
        backgroundContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

        return backgroundContext
    }()
}

We build a NSFetchedResultsController around CoreDataStack.INSTANCE.persistentContainer.viewContext

Even when the write operation is performed using CoreDataStack.INSTANCE.backgroundContext, NSFetchedResultsController is still able to receive notification, due to the following line

// So that when backgroundContext write to persistent store, container.viewContext will retrieve update from
// persistent store.
container.viewContext.automaticallyMergesChangesFromParent = true

When I try to observe Core Data change manually, via

notificationCenter.addObserver(
    self, 
    selector: #selector(managedObjectContextDidSave), 
    name: NSNotification.Name.NSManagedObjectContextDidSave, 
    object: viewContext
)

We do not receive notification when backgroundContext perform write.

It will only work if we observe using the following way

notificationCenter.addObserver(
    self, 
    selector: #selector(managedObjectContextDidSave), 
    name: NSNotification.Name.NSManagedObjectContextDidSave, 
    object: backgroundContext
)

May I know why it is so? Why automaticallyMergesChangesFromParent work for NSFetchedResultsController, but not the manual NotificationCenter observing?



Solution 1:[1]

Let me suppose that this happens because viewContext does not actually save anything. It just reads back from parent - persistent store coordinator. It is the backgroundContext that saves to itself (and to its parent - persistent store coordinator). ?

NSNotification.Name.NSManagedObjectContextDidMergeChangesObjectIDs?

Might work to observe merging into viewContext.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Paul B