问题
There is a similar question in stack overflow already but it doesn't work for me.
There is a use case in my application where I have to observe the database changes to perform some operation. To receive updates I subscribed to NSManagedObjectContextObjectsDidChange
notification (for ViewContext) and also I turned on automaticallyMergesChangesFromParent
.
But, if I update
or delete
the object on some other context (using newBackgroundContext()
), I don’t receive object did change notification but it’s working perfectly for inserting
new objects.
Can you someone please guide me why it does work only for insert, not for update and delete even after enabling automaticallyMergesChangesFromParent
? if it's the actual behavior, Is there any other way to solve my use case?
The documentation (in NSManagedObjectContext.h
) for .automaticallyMergesChangesFromParent
says:
Whether the context automatically merges changes saved to its coordinator or parent context. Setting this property to YES when the context is pinned to a non-current query generation is not supported.
What I tried
- I debugged by testing if updated/deleted objects are already registered in the view context. Yes, those are already registered.
- I tested the same thing using
NSFetchResultController
it’s working good but unfortunately, I can’t useNSFetchResultController
as I use a custom view to represent the data - Also, I tried creating a new
privateQueueConcurrencyType
context and settingviewContext
as a parent and it surprisingly started working so the issue is only while usingnewBackgroundContext()
but as per document it should work properly as both are using sameNSPersistentStoreCoordinator
Thanks in advance!
回答1:
"I can’t use NSFetchResultController
as I use a custom view to represent the data" not true, the FRC can and should be used with any view (that shows multiple objects).
As for why you are not receiving the NSManagedObjectContextObjectsDidChange
in the case of updates (which come in as refreshed) or deletes I have a few theories:
Maybe not properly called
_persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;
because that causes exactly the situation you describe (receiving inserts but not updates or deletes). It should be done in the persistentContainer custom getter in your app delegate afterloadPersistentStoresWithCompletionHandler
(and not inside the block).Perhaps not using
performBlock
with your background context.Possibly not registered for the did change notification correctly.
(In light of new information) Not retaining the fetched objects.
If you would like to share some code we can help you track down the bug.
回答2:
Probably not totally an answer but just some thoughts and suggestions that are not well enough structured for a comment.
It could be related to the viewContext not retaining the objects, rather just faults because they weren't being used anymore directly (such as in a tableview). There would be retainsRegisteredObjects for that.
Also, did you ever access the property that has been changed in the viewContext? That could also be an issue, that it wont recognize a change on an object that never got read.
I strongly recommend using one or multiple FRC for those cases, they bridge the notifications for you and provide a cleaner interface. It does not matter if you have a custom view, just implement the FRCDelegate methods and you will be fine. I think it could be easier to help you if you ask another question why you cannot use FRC (where are the problems?) with your custom view.
来源:https://stackoverflow.com/questions/56836484/viewcontext-not-receiving-updates-from-newbackgroundcontext