We're seeing a rare issue in the field that I haven't been able to reproduce. The app primarily uses a main queue managed object context, with a couple of other private queue contexts for specialized cases. Those cases do not modify objects that are also modified in the main queue context, so we haven't done anything to specifically handle merge conflicts. We shouldn't have any during normal operation.
In at least one case, a user transitions from background to foreground and back to background in a short period of time. One of the things we do when transitioning to inactive state is to save the main queue context. During this save, sometimes it appears that all of the objects loaded in the main queue context will become conflicted. When this happens, the conflicts are very odd:
Failed to save: Error Domain=NSCocoaErrorDomain Code=133020 "Could not merge changes." UserInfo={conflictList=(
"NSMergeConflict (0x11d8ec540) for NSManagedObject (0x11bf50990) with objectID '0xd00000000f340014 <x-coredata://36EBC17F-A244-4CE0-BB10-C0C5C2C3AFC1/Document/p973>' with oldVersion = 0 and newVersion = 4 and old object snapshot = { ... all attributes are null ... } and new cached row = { ... all attributes have the expected values ... }"
I've encountered merge conflicts in the past, and they're due to modifications made in two contexts simultaneously. Here, we aren't modifying simultaneously, the oldVersion value is 0 and the old object snapshot is an empty object (none of the attributes are set to a value).
Has anyone else seen this behavior? Is there an explanation for how an object could have an oldVersion = 0?
Also, the docs don't provide quite enough detail for me to understand the difference between an "object snapshot" and a "cached row".