Reputation: 311
I'm having a terrible problem. I'm saving a managedObject "Customer" with field sync as false
using my main MOC. Then after syncing with server, I use a private MOC to save the Customer with sync field as true
. When I save this, notification is passed and the main MOC saves the customer correctly. Then when I edit that customer, the same process happens. But this time, even if the sync field is true
, upto the point where private MOC saves it, the notification got at the other end contains Customer with sync as false
. If I repeat the process, sync becomes true
. Instead of repeating, if I am saving some other data using the private MOC, then with that notification, Customer also comes with sync field as true
. I don't understand why notification method is not working correctly. In addObserver
of didsavenotification, I have specified the object
as the private MOC itself. Somebody please help.
These are the code snippets prominent in this flow.
//Assigning false
selectedCustomer.synced = NSNumber(bool: false)
//Saving using main MOC
try managedObjectContext.save()
//Assigning synced details to a dictionary
let cust: CustomerDetails = CustomerDetails(data: customer)
cust.synced = true
//Assigning dictionary to customer managedObject fetched from coredata using private MOC
assignData(customerDetails, toCustomer: customer)
//Saving the private MOC
try syncManagedObjectContext.save()
//Getting notification and saving
managedObjectContext.performBlock { () -> Void in self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
}
//Registration of notification
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: #selector(AppDelegate.managedObjectContextDidSave(_:)), name: NSManagedObjectContextDidSaveNotification, object: syncManagedObjectContext)
EDIT:
These are the definitions of the MOCs I'm using
lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
lazy var syncManagedObjectContext: NSManagedObjectContext = {
let coordinator = self.managedObjectContext.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
Upvotes: 0
Views: 143
Reputation: 46718
Show how you defined your MOCs as well.
Are they parent child?
Are they siblings against the NSPersistentStoreCoordinator
?
This can have an impact.
I would also turn on -com.apple.CoreData.ConcurrencyDebug 1
and run your app again as this sounds like a threading issue.
As your NSManagedObjectContext
instances are siblings you really need to turn on the currency debug flag and run again. This really reads like a threading issue.
There is not a lot of code in your question to try and deduce an answer if this is not a threading issue.
My next suggestion would be to move your private MOC from a sibling to a child (Apple's documentation on threading discusses this) and stop using the notification (unnecessary with child MOCs).
If the issue is still there then you are going to need to trace it in the debugger and find out at what point the issue surfaces. It can still be a threading issue without being a "touched the wrong object on the wrong thread" issue. Is the property being changed when you think it is? Using the debugger is the only way to be certain.
Upvotes: 1