【发布时间】:2022-12-31 03:41:00
【问题描述】:
我正在制作简单的应用程序,用于跟踪卡路里。它将数据存储在简单的 CoreData 模型中。 这是我负责创建数据模型的代码。
它很简单,并且基于 Xcode 生成的代码。
import Foundation
import CoreData
class PersistenceController: ObservableObject {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
container = NSPersistentContainer(name: "FoodModel")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
func save(context: NSManagedObjectContext) {
do {
try context.save()
print("Data has been saved successfully.")
} catch {
// Handle errors in our database
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
func addFood(name: String, calories: Double, context: NSManagedObjectContext) {
let food = Food(context: context)
food.id = UUID()
food.date = Date()
food.name = name
food.calories = calories
save(context: context)
}
func editFood(food: Food, name: String, calories: Double, context: NSManagedObjectContext) {
food.date = Date()
food.name = name
food.calories = calories
save(context: context)
}
}
在尝试加餐时,我从 CoreData 收到此警告:
2022-09-06 17:52:24.248483+0200 TrackCalories[67203:10277525] [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'TrackCalories.Food' so +entity is unable to disambiguate.
警告最终导致错误:
CoreData: error: +[TrackCalories.Food entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
当然,除了警告和 CoreData 错误之外,我的实现工作正常并且数据已正确保存。
错误和警告仅在我尝试添加新餐时出现。
值得一提的是,当我修改现有条目或删除它时,不会出现警告和错误。
所以上面的函数:addFood和save负责数据的添加和保存。
这是应该调用上述函数的代码:
struct AddFoodView: View {
@Environment(\.managedObjectContext) var managedObjContext
@Environment(\.dismiss) var dismiss
@State private var name = ""
@State private var calories: Double = 0
var body: some View {
Form {
Section() {
TextField("What have you eaten?", text: $name)
VStack {
Text("Calories: \(Int(calories))")
Slider(value: $calories, in: 0...2000, step: 10)
}
.padding()
HStack {
Spacer()
Button("Add meal") {
PersistenceController().addFood(
name: name,
calories: calories,
context: managedObjContext)
dismiss()
}
Spacer()
}
}
}
}
}
struct AddFoodView_Previews: PreviewProvider {
static var previews: some View {
AddFoodView()
}
}
感谢@TomHarrington 问题现在已经解决了。所有的功劳都归于他。
每次我向 CoreData 添加新餐时,我都在创建 PersistanceController 的新实例。
解决方案是通过不可变变量static let shared来访问实例。
AddFoodView 中的工作代码是:
PersistenceController.shared.addFood(
name: name,
calories: calories,
context: managedObjContext)
dismiss()
}
【问题讨论】:
-
清理构建文件夹,看看是否有帮助。
-
感谢@JoakimDanielson 的建议,不幸的是,我在删除派生数据之前曾尝试清理它。它没有帮助:/
-
也许您可以共享保存新对象的代码
-
你有没有可能不小心创建了多个
PersistenceController? -
@RalphL 我不是 SwiftUI 专家,但看起来每次单击“加餐”按钮时,都会创建一个新的
PersistenceController。这可能是个坏主意。