数据文件Fopen失败:errno = 2(没有这样的文件或目录)/ Swift / SwiftUI / iOS 16 / CoreData

问题描述 投票:0回答:1

大家好!我有一个大型项目,其中有多个 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()
        }
    }
}

欢迎就此问题提出任何建议! 谢谢大家,祝你有美好的一天!

swift swiftui core-data ios16
1个回答
0
投票

最终我成功解决了这个问题...

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



但是,我不明白为什么 Xcode 将此错误归因于 iPhone 日志中的 CoreData...



无论如何,我的主应用程序一直运行良好,现在仍然如此。但是,删除 .drawingGroup() 修饰符后,该错误在应用程序首次启动时消失了。我相信这是 SwiftUI 的 .drawingGroup() 修饰符中的一个错误,该错误尚未修复。我认为苹果应该修复这个错误。如果在应用程序首次启动时使用 .drawingGroup() 修饰符,则如果视图尚未作为图像渲染到内存中,则只需渲染它即可。开发人员不应该看到有关缺少某些文件的无信息消息,该消息总是在程序首次启动时生成。

在 SwiftUI 中使用 .drawingGroup() 修饰符时要小心,并始终在应用程序第一次启动时测试它的工作原理。最有可能的是,您的应用程序将继续正常工作,您的视图将被编译并作为图像保存在内存中,但此消息可能会在将来吓到您和您的团队。您可能会像我一样花费大量时间寻找错误,但这并不完全是错误。我认为这条消息可以忽略......但就我而言,我选择不使用 SwiftUI 中的 .drawingGroup() 修饰符,因此错误消失了,应用程序开始使用更少的 RAM。

我希望我的时间没有被浪费,这些信息将对其他人有所帮助!

祝大家有美好的一天,快乐编码!


© www.soinside.com 2019 - 2024. All rights reserved.