我正尝试在下面使用此方法来保存或创建GameMO
对象,该对象是NSManagedObject
的子类。问题是,当我在更改winnerChanged()
的选定值时调用下面的UISegmentedControl
方法时,在下面调用了此saveOrCreateGameMO()
方法,最终创建了一个新的GameMO对象,存储在CoreData而不是加载已经存在于CoreData中的一个并对其进行更新。我不知道为什么会这样。这是我更改游戏获胜者时在日志中看到的内容:
Saving game because winner was changed
Updating Game to CoreData
这告诉我游戏正在尝试更新已经存在的GameMO对象,因为NSPredicate
中的FetchRequest
评估为true,并在CoreData中找到至少一个具有相同{{ 1}}(只是一个随机的UUID字符串),并且正在使用它而不是创建一个新的字符串。
更令人困惑的是,我第一次运行我的应用程序(将其从模拟器中完全删除以重置CoreData的持久性存储后),它从id
和{中弹出Updating Conference to CoreData
和Updating Team to CoreData
{1}},表明它已经以某种方式找到了saveOrCreateConference()
这样的NSPredicate有效值。如果清除了持久存储,怎么可能?我还在下面介绍了如何加载游戏。
saveOrCreateTeam()
NSPredicate(format: "name == %@", teamMO.name)
@IBAction func winnerChanged(_ sender: UISegmentedControl) {
os_log("Saving game because winner was changed", type: .debug)
let viewcell = sender.superview?.superview as? ConferenceGamesTableViewCell
guard viewcell != nil else {
os_log("viewcell is nil in winnerChanged in ConferenceGamesTableViewController", type: .debug)
return
}
guard let game = viewcell?.game else {
os_log("Could not unwrap game in winnerChanged in ConferenceGamesTableViewController", type: .debug)
return
}
guard let winnerName = sender.titleForSegment(at: sender.selectedSegmentIndex) else {
os_log("Could not unwrap game winner from UISegmentedControl in ConferenceGamesTableViewController", type: .debug)
return
}
guard let winnerConferenceName = Conference.name(forTeamName: winnerName) else {
os_log("Could not unwrap game winner conference name in ConferenceGamesTableViewController", type: .debug)
return
}
game.winner = Team(teamName: winnerName, conferenceName: winnerConferenceName)
guard let gameMO = GameMO.newGameMO(fromGame: game) else {
os_log("Could not unwrap gameMO from game in ConferenceGamesTableViewController", type: .debug)
return
}
let dataModelManager = DataModelManager.shared
dataModelManager.saveOrCreateGameMO(gameMO: gameMO)
}
public func saveOrCreateGameMO(gameMO: GameMO) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "GameMO")
fetchRequest.predicate = NSPredicate(format: "id == %@", gameMO.id)
do {
let test = try managedContext.fetch(fetchRequest)
let objectUpdate = test[0] as! GameMO
objectUpdate.setValue(gameMO.id, forKey: "id")
objectUpdate.setValue(gameMO.conferencesNames, forKeyPath: "conferencesNames")
objectUpdate.setValue(gameMO.confidence, forKeyPath: "confidence")
objectUpdate.setValue(gameMO.contestantsNames, forKeyPath: "contestantsNames")
objectUpdate.setValue(gameMO.winnerName, forKeyPath: "winnerName")
do {
try managedContext.save()
os_log("Updating Game to CoreData", type: .debug)
} catch let error as NSError {
print("Could not update game to CoreData. \(error), \(error.userInfo)")
}
} catch {
os_log("Could not fetch game from CoreData. Saving it as a new game.", type: .debug)
let entity = NSEntityDescription.entity(forEntityName: "Game", in: managedContext)!
let newGameMO = GameMO(entity: entity, insertInto: managedContext)
newGameMO.setValue(gameMO.id, forKey: "id")
newGameMO.setValue(gameMO.conferencesNames, forKeyPath: "conferencesNames")
newGameMO.setValue(gameMO.confidence, forKeyPath: "confidence")
newGameMO.setValue(gameMO.contestantsNames, forKeyPath: "contestantsNames")
newGameMO.setValue(gameMO.winnerName, forKeyPath: "winnerName")
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save new game to CoreData. \(error), \(error.userInfo)")
}
}
}