Fixes crashes when loading Game or SaveState that had been overwritten by a duplicate entry

When Core Data detects a duplicate entry, it deletes the previous entry. This caused Delta to delete the associated ROM and Save State files. Now, there is a check in prepareForDeletion to make sure the object being deleted is not simply being replaced by a newer entry during a merge.
This commit is contained in:
Riley Testut 2016-12-26 15:56:33 -06:00
parent 9648aec3b5
commit 5c6c66c9a1
2 changed files with 27 additions and 18 deletions

View File

@ -30,6 +30,12 @@ extension Game
{ {
super.prepareForDeletion() super.prepareForDeletion()
guard let managedObjectContext = self.managedObjectContext else { return }
// If a game with the same identifier is also currently being inserted, Core Data is more than likely resolving a conflict by deleting the previous instance
// In this case, we make sure we DON'T delete the game file + misc other Core Data relationships, or else we'll just lose all that data
guard !managedObjectContext.insertedObjects.contains(where: { ($0 as? Game)?.identifier == self.identifier }) else { return }
guard FileManager.default.fileExists(atPath: self.fileURL.path) else { return } guard FileManager.default.fileExists(atPath: self.fileURL.path) else { return }
do do
@ -41,8 +47,6 @@ extension Game
print(error) print(error)
} }
if let managedObjectContext = self.managedObjectContext
{
for collection in self.gameCollections where collection.games.count == 1 for collection in self.gameCollections where collection.games.count == 1
{ {
// Once this game is deleted, collection will have 0 games, so we should delete it // Once this game is deleted, collection will have 0 games, so we should delete it
@ -61,5 +65,4 @@ extension Game
managedObjectContext.saveWithErrorLogging() managedObjectContext.saveWithErrorLogging()
} }
} }
}
} }

View File

@ -60,6 +60,12 @@ public class SaveState: _SaveState, SaveStateProtocol
// In rare cases, game may actually be nil if game is corrupted, so we ensure it is non-nil first // In rare cases, game may actually be nil if game is corrupted, so we ensure it is non-nil first
guard self.game != nil else { return } guard self.game != nil else { return }
guard let managedObjectContext = self.managedObjectContext else { return }
// If a save state with the same identifier is also currently being inserted, Core Data is more than likely resolving a conflict by deleting the previous instance
// In this case, we make sure we DON'T delete the save state file + misc other Core Data relationships, or else we'll just lose all that data
guard !managedObjectContext.insertedObjects.contains(where: { ($0 as? SaveState)?.identifier == self.identifier }) else { return }
guard FileManager.default.fileExists(atPath: self.fileURL.path) else { return } guard FileManager.default.fileExists(atPath: self.fileURL.path) else { return }
do do