【发布时间】:2020-06-30 22:41:40
【问题描述】:
编辑 *********
2020 年 7 月 9 日下午 1:39(太平洋标准时间)
我有我认为足够的应用程序的最小工作可复制版本,可在以下位置获得:
https://github.com/Rattletrap99/penny-game-test
编辑 *********
我正在构建一个游戏,用户可以在其中创建硬币作为各种成就的奖励。硬币在 Core Data 中保存为托管对象,具有各种属性。在游戏过程中,出于各种原因检索它们、修改它们的属性等。
一切都完美地保存和检索,直到我退出并重新启动,此时持久存储中不存在任何数据。无论是使用模拟器还是设备都是如此。
我通常保存到 Core Data 的方法是:
func saveIt(){
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
appDelegate.saveContext()
}
调用者:
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
savedFlag += 1
let coinFetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Coin")
let savedCoins = try context.fetch(coinFetchRequest) as! [Coin]
print("In appDelegate, saveContext, after context.save, there are \(savedCoins.count) coins.")
print("Successfully saved in appDelegate \(String(describing: savedFlag)) times")
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
我在代码中输入的每个print() 语句都会确认保存,但是当我检索(重新启动时)时,通过类似于以下代码:
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let issuerFetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Issuer")
let coinFetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Coin")
do {
let issuers = try context.fetch(issuerFetchRequest) as! [Issuer]
print(" ### Upon startup, there are \(issuers.count) Issuers in CD")
let coins = try context.fetch(coinFetchRequest) as! [Coin]
print(" #### Upon startup, there are \(coins.count) Coins in CD")
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
我明白了:
### Upon startup, there are 0 Issuers in CD
#### Upon startup, there are 0 Coins in CD
另外,我尝试保存在applicationWillTerminate 以确保在退出前保存数据:
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
let issuerFetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Issuer")
let coinFetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Coin")
do {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let issuers = try context.fetch(issuerFetchRequest) as! [Issuer]
let coins = try context.fetch(coinFetchRequest) as! [Coin]
print("\\\\ Upon quit, there are \(issuers.count) Issuers in CD")
print("\\\\ Upon quit, there are \(coins.count) Coins in CD")
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
但是,print() 声明没有打印出来,这让我相信 applicationWillTerminate 永远不会被解雇。
我应该提到Issuer 与Coin 有to many 关系,并且我确保在创建和保存Coin 之前存在Issuer。
非常感谢任何帮助!
【问题讨论】:
-
你能提交一个最小的可复现版本的代码到 git 吗?
-
另外,您的核心数据存储是否由 sqlite 支持?您可以尝试使用 sqlite 浏览器检查 sqlite 文件,以检查数据是否正确存储在那里。如果是,那么您可以缩小到代码的检索部分。
-
@ReinhardMänner -- 最低工作时间:github.com/Rattletrap99/penny-game-test。但是,尽管多次尝试,我似乎无法添加 xcdatamodel 文件。任何指导表示赞赏...
-
@ReinhardMänner -- 我尝试根据您的建议更改 fetchRequest,但结果是一样的。持久存储中的零数据...