我是 swift 新手,我无法理解环境变量的工作原理。
在 Core Data 中,我创建了一个名为“API”的新实体,它具有一个属性 id:Int32。
然后在 SwiftUI 中,我想找到 id 的最大值。我写了一个请求,但是每当我使用传递给视图作为环境变量 managedObjectContext 时,它总是使我的应用程序/预览崩溃。这是使用 NSManagedObjectContext.fetch(NSFetchRequest) 后的崩溃信息(使用 FetchRequest 仅提供带有异常 EXC_BAD_INSTRUCTION 的堆栈跟踪)
...
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
External Modification Warnings:
Thread creation by external task.
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The fetch request's entity 0x600003c54160 'API' appears to be from a different NSManagedObjectModel than this context's'
terminating with uncaught exception of type NSException
abort() called
CoreSimulator 704.12 - Device: iPhone 11 (8356FF2A-5F0A-42F7-AA32-396FADCF2BF6) - Runtime: iOS 13.4 (17E255) - DeviceType: iPhone 11
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff23e3dcce __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50b3b9b2 objc_exception_throw + 48
2 CoreData 0x00007fff239c6b99 -[NSManagedObjectContext executeFetchRequest:error:] + 5004
3 libswiftCoreData.dylib 0x00007fff513b63d4 $sSo22NSManagedObjectContextC8CoreDataE5fetchySayxGSo14NSFetchRequestCyxGKSo0gH6ResultRzlF + 68
...
请记住,此错误会根据我使用的项目而变化。在我的主要项目中,我遇到了这样的错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'WebsiteAPI''
这是我正在使用的代码
import SwiftUI
import CoreData
struct test: View {
private var id: Int32
@Environment(\.managedObjectContext) var managedObjectContext
var body: some View {
Text("id=\(id)")
}
public init(context: NSManagedObjectContext) {
self.id = -1
//this crashes and gives no usefull information
// let request2 = FetchRequest<API>(
// entity: API.entity(),
// sortDescriptors: [NSSortDescriptor(keyPath: \API.id, ascending: false)]
// )
// self.id = request2.wrappedValue.first?.id ?? 1
guard let context2 = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
fatalError("Unable to read managed object context.")
}
let request = NSFetchRequest<API>(entityName: "API")
request.sortDescriptors = [NSSortDescriptor(keyPath: \API.id, ascending: false)]
do {
var commits = try context.fetch(request) // OK
commits = try context2.fetch(request) // OK
//commits = try self.managedObjectContext.fetch(request) // causing crash
self.id = Int32(commits.count)
} catch let error {
print(error.localizedDescription)
}
}
}
struct test_Previews: PreviewProvider {
static var previews: some View {
guard let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
fatalError("Unable to read managed object context.")
}
return test(context: context).environment(\.managedObjectContext, context)
}
}
所有评论的行崩溃应用程序。为什么从 AppDelegate.persistentContainer.viewContext 获取上下文工作得很好,但是使用我认为应该相同的环境变量 managedObjectContext 不起作用?我花了5个小时,检查了几乎所有东西,尝试了很多东西但没有成功。最后我可以继续从 AppDelegate 获取上下文,但是环境变量有什么问题?我错过了一些常识还是只是一个错误?我对在 Xcode 中遇到的错误感到头疼,从清除构建文件夹后缺少自动完成到更改所有引用的结构/文件名后出现数百个错误,尽管之后成功构建。每天重启几次 Xcode 以使其正常工作对我来说是正常的。
还有一些我注意到的事情,当我将 FetchRequest 创建为变量并在正文中的某个列表中使用它时,它起作用了。问题仅在于,当我尝试在代码/函数/init 中手动获取内容时,例如按钮操作或方法 onAppear、init 等。我尝试在物理设备上运行应用程序并显示预览。一样的效果。
我将 Xcode 11.4 与 Swift 5 一起使用。