大家好!我有一个大型项目,其中有多个 CoreData 容器。 当您首次在模拟器或真实设备上打开应用程序时,调试器中会弹出此错误。
但是,我的应用程序运行完美,没有任何崩溃,我很长一段时间都忽略了这个错误。今天我一整天都在寻找解决这个问题的方法...
因此,这个错误的具体原因并不那么容易理解。现在我创建了一个新的小项目并开始配置 CoreData。我又遇到了这个错误。 通过真机的日志可以追踪到这个错误的原因。 这里确认了 CoreData 是罪魁祸首。
该错误仅在首次启动应用程序时出现,尽管如此,带有 CoreData 的应用程序运行良好 - 所有数据都存储在 CoreData 中并从中检索。
我的猜测...
数据文件 fopen 失败:errno = 2(没有此类文件或目录)
我假设当应用程序第一次启动时,SQLite 文件根本不存在,这就是弹出此错误的原因,但此文件已创建并且一切正常。 我想指出的是,当再次启动应用程序时,不会出现此错误,因为 SQLite 文件已经创建。
我已经为解决方案做了什么。
Cmd + shift + K - 不能解决这个问题。
我在 Stackoverflow 上看到,由于使用 Metal API,用户出现了此错误 - 我禁用了 Metal API 验证技术。
通过调试面板对CoreData文件创建的检查也进行了检查。就像我说的,一切都很好。
该错误出现在两台装有 Xcode 14.3.1 和 Xcode 15 Beta 8 的 MacBook、Ventura 和 Sonoma 以及所有模拟器和真实设备上。
为了测试和检查,创建了一个新项目,该项目也存在此问题。
测试 CoreData...
import Foundation
import CoreData
final class UserEventsCoreDataManager {
static let instance = UserEventsCoreDataManager()
let container: NSPersistentContainer
let context: NSManagedObjectContext
init() {
container = NSPersistentContainer(name: "UserEventsCoreDataContainer")
container.loadPersistentStores { description, error in
if let error = error {
print("Error loading CoreData: \(error)")
}
}
context = container.viewContext
}
func save() {
do {
try context.save()
print("Saved successfully!")
} catch let error {
print("Error saving CoreData. \(error.localizedDescription)")
}
}
}
final class UserEventsViewModel: ObservableObject {
let dataManager = UserEventsCoreDataManager.instance
@Published var categories: [UserEventCategoryEntity] = []
init() {
fetchCategories()
}
func fetchCategories() {
let request = NSFetchRequest<UserEventCategoryEntity>(entityName: "UserEventCategoryEntity")
do {
categories = try dataManager.context.fetch(request)
} catch let error {
print("Error fetching Categories: \(error)")
}
}
func addCategory() {
let newCategory = UserEventCategoryEntity(context: dataManager.context)
newCategory.categoryTitle = "My Parties"
newCategory.categoryType = "parties"
newCategory.events = []
save()
}
func addHoliday() {
let newEvent = UserEventItemEntity(context: dataManager.context)
newHoliday.eventTitle = "AVB / ASOT 1000"
newHoliday.categories = categories[0]
save()
}
func save() {
categories.removeAll()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.dataManager.save()
self.fetchCategories()
}
}
}
欢迎就此问题提出任何建议! 谢谢大家,祝你有美好的一天!
最终我成功解决了这个问题...
应用程序首次启动时控制台中指定消息的罪魁祸首是 SwiftUI 中的 .drawingGroup() 修饰符。此修改器将您的视图作为图像存储在内存中,因此应用程序不必每次都重新编译它。这个解决方案很好,您的应用程序可以在旧版 iPhone 上顺利运行,尽管它使用更多 RAM。然而,在内存中第一次启动应用程序时,视图的渲染尚未创建,因此在某些情况下,我们可能会收到这样的消息...
但是,我不明白为什么 Xcode 将此错误归因于 iPhone 日志中的 CoreData...
无论如何,我的主应用程序一直运行良好,现在仍然如此。但是,删除 .drawingGroup() 修饰符后,该错误在应用程序首次启动时消失了。我相信这是 SwiftUI 的 .drawingGroup() 修饰符中的一个错误,该错误尚未修复。我认为苹果应该修复这个错误。如果在应用程序首次启动时使用 .drawingGroup() 修饰符,则如果视图尚未作为图像渲染到内存中,则只需渲染它即可。开发人员不应该看到有关缺少某些文件的无信息消息,该消息总是在程序首次启动时生成。
在 SwiftUI 中使用 .drawingGroup() 修饰符时要小心,并始终在应用程序第一次启动时测试它的工作原理。最有可能的是,您的应用程序将继续正常工作,您的视图将被编译并作为图像保存在内存中,但此消息可能会在将来吓到您和您的团队。您可能会像我一样花费大量时间寻找错误,但这并不完全是错误。我认为这条消息可以忽略......但就我而言,我选择不使用 SwiftUI 中的 .drawingGroup() 修饰符,因此错误消失了,应用程序开始使用更少的 RAM。
我希望我的时间没有被浪费,这些信息将对其他人有所帮助!
祝大家有美好的一天,快乐编码!