1

I recently managed to catch an extremely rare exception in my code and was hoping folks here could help me understand it. I have a game which is tracking elapsed time and persisting the value to Core Data every second. At the same time a user could be playing the game and causing the score to update, which is also saved in Core Data. I suspect that I should be serializing saves, but at the moment I'm not. Everything works great 99.99% of the time, but once in a while the call to context.save() throws an exception.

I have a merge policy set as so:

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

And here's how I save elapsed time. The same pattern is used for updating a player's score.

func saveElapsedTime() {
    let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
    container.performBackgroundTask() { (context) in
        let storedGame = context.object(with: self.storedGameID) as! StoredGame
        storedGame.elapsedTime = Int32(self.elapsedTime)

        do {
            try context.save()
        } catch let nserror as NSError {
            print("saveElapsedTime: failed to save: \(nserror). userInfo: \(nserror.userInfo).")
        }
    }
}

The rare error I was able to catch looks like this:

Error Domain=NSCocoaErrorDomain Code=133020 "Could not resolve merge changes."
<snip>...with oldVersion = 463 and newVersion = 463...<snip>

I've seen plenty of posts where the old and new versions are off by one or a small number, and people recommend setting a merge policy which is different than the default. I'm guessing that in my case where oldVersion == newVersion it's because multiple threads are trying to save at the exact same time. Can someone confirm this just by looking at the error message? Should I be serializing all saves using an OperationQueue like in this example: NSPersistentContainer concurrency for saving to core data?

Thanks in advance.

Russ Neufeld
  • 123
  • 1
  • 6

0 Answers0