数据文件的Fopen失败:errno = 2(No such file or directory)/ Swift / SwiftUI / iOS 16 / CoreData

0kjbasz6  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(388)

大家好!我有一个大型项目,其中有几个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和索诺马以及所有模拟器和真实的设备上。
  • 为了进行测试和检查,创建了一个新项目,该项目上也存在此问题。
    正在测试CoreData...
  1. import Foundation
  2. import CoreData
  3. final class UserEventsCoreDataManager {
  4. static let instance = UserEventsCoreDataManager()
  5. let container: NSPersistentContainer
  6. let context: NSManagedObjectContext
  7. init() {
  8. container = NSPersistentContainer(name: "UserEventsCoreDataContainer")
  9. container.loadPersistentStores { description, error in
  10. if let error = error {
  11. print("Error loading CoreData: \(error)")
  12. }
  13. }
  14. context = container.viewContext
  15. }
  16. func save() {
  17. do {
  18. try context.save()
  19. print("Saved successfully!")
  20. } catch let error {
  21. print("Error saving CoreData. \(error.localizedDescription)")
  22. }
  23. }
  24. }
  25. final class UserEventsViewModel: ObservableObject {
  26. let dataManager = UserEventsCoreDataManager.instance
  27. @Published var categories: [UserEventCategoryEntity] = []
  28. init() {
  29. fetchCategories()
  30. }
  31. func fetchCategories() {
  32. let request = NSFetchRequest<UserEventCategoryEntity>(entityName: "UserEventCategoryEntity")
  33. do {
  34. categories = try dataManager.context.fetch(request)
  35. } catch let error {
  36. print("Error fetching Categories: \(error)")
  37. }
  38. }
  39. func addCategory() {
  40. let newCategory = UserEventCategoryEntity(context: dataManager.context)
  41. newCategory.categoryTitle = "My Parties"
  42. newCategory.categoryType = "parties"
  43. newCategory.events = []
  44. save()
  45. }
  46. func addHoliday() {
  47. let newEvent = UserEventItemEntity(context: dataManager.context)
  48. newHoliday.eventTitle = "AVB / ASOT 1000"
  49. newHoliday.categories = categories[0]
  50. save()
  51. }
  52. func save() {
  53. categories.removeAll()
  54. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  55. self.dataManager.save()
  56. self.fetchCategories()
  57. }
  58. }
  59. }

欢迎大家对这个问题提出建议!谢谢大家,祝你们有愉快的一天!

plicqrtu

plicqrtu1#

最后,我设法解决了这个问题...
第一次启动应用程序时,控制台中出现指定消息的罪魁祸首是SwiftUI中的.drawingGroup()修饰符。此修改器将您的视图作为图像存储在内存中,这样应用程序就不必每次都重新编译它。这个解决方案很好,你的应用程序在旧版本的iPhone上运行流畅,尽管它使用更多的RAM。然而,在应用程序在内存中第一次启动时,视图的呈现尚未创建,因此在某些情况下,我们可能会收到这样的消息...

然而,我不明白为什么Xcode在iPhone日志中将此错误归因于CoreData。

无论如何,我的主要应用程序一直工作得很好,现在仍然如此。但是,删除.drawingGroup()修饰符后,应用程序首次启动时错误消失了。我相信这是SwiftUI的.drawingGroup()修饰符中的一个bug,它仍然没有修复。我认为苹果应该修复这个bug。如果在应用程序第一次启动时使用.drawingGroup()修饰符,如果视图尚未作为图像呈现到内存中,则只需要呈现它。开发人员不应该看到关于缺少某个文件的无意义消息,这总是在程序首次启动时生成的。
在SwiftUI中使用.drawingGroup()修饰符时要小心,并始终在应用首次启动时测试它的工作方式。最有可能的是,您的应用程序将继续正常工作,您的视图将被编译并作为图像保存在内存中,但此消息可能会在将来吓到您和您的团队。你可以像我一样花很多时间去找一个bug,但它并不完全是一个bug。我认为这个信息可以忽略。。但在我的例子中,我选择在SwiftUI中不使用.drawingGroup()修饰符,所以错误消失了,应用程序开始使用更少的RAM。
我希望我的时间没有被浪费,这些信息将帮助别人!
祝大家有一个美好的一天,编码快乐!

展开查看全部

相关问题