You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CoreData中FetchedResults无法初始化问题求助

问题分析与解决方案

错误的核心原因是**FetchedResults<Device>没有公开的初始化器**,你不能直接通过FetchedResults<Device>(fetchRequest: ..., managedObjectContext: ...)这种方式创建实例。FetchedResults是SwiftUI为CoreData专门设计的类型,只能通过@FetchRequest属性包装器或者底层的NSFetchedResultsController间接获取。

以下是两种适配你场景的解决办法:

方式一:在SwiftUI视图中直接使用@FetchRequest获取已保存设备

如果你的DeviceListView是SwiftUI视图,可以直接在视图内部用@FetchRequest获取CoreData中的Device实体,无需在CoreDataController中手动创建FetchedResults:

struct DeviceListView: View {
    // 直接通过@FetchRequest获取已保存设备
    @FetchRequest(fetchRequest: Device.fetchRequest()) var savedDevices: FetchedResults<Device>
    // 新发现设备列表,从BLECentralManager获取
    @State var discoveredDevices: [BLEDevice] = []
    
    var body: some View {
        List {
            Section("已保存设备") {
                ForEach(savedDevices) { device in
                    Text(device.name ?? "未知设备")
                }
            }
            
            Section("新发现设备") {
                ForEach(discoveredDevices) { device in
                    Text(device.name)
                }
            }
        }
    }
}

方式二:在CoreDataController中使用NSFetchedResultsController管理数据

如果需要在CoreDataController中封装CoreData逻辑,可以用NSFetchedResultsController来监听数据变化,并将结果发布给视图:

class CoreDataController: ObservableObject {
    let persistentContainer: NSPersistentContainer
    // 发布已保存设备列表,供视图订阅
    @Published var savedDevices: [Device] = []
    
    private var fetchedResultsController: NSFetchedResultsController<Device>?
    
    init() {
        persistentContainer = NSPersistentContainer(name: "YourDataModel")
        persistentContainer.loadPersistentStores { _, error in
            if let error = error {
                fatalError("CoreData加载失败: \(error.localizedDescription)")
            }
            self.setupFetchedResultsController()
        }
    }
    
    private func setupFetchedResultsController() {
        let fetchRequest: NSFetchRequest<Device> = Device.fetchRequest()
        // 可以添加排序规则,比如按名称排序
        fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Device.name, ascending: true)]
        
        fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: persistentContainer.viewContext,
            sectionNameKeyPath: nil,
            cacheName: nil
        )
        
        fetchedResultsController?.delegate = self
        
        do {
            try fetchedResultsController?.performFetch()
            savedDevices = fetchedResultsController?.fetchedObjects ?? []
        } catch {
            print("获取设备失败: \(error.localizedDescription)")
        }
    }
}

// 实现NSFetchedResultsControllerDelegate,监听数据变化
extension CoreDataController: NSFetchedResultsControllerDelegate {
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        guard let devices = controller.fetchedObjects as? [Device] else { return }
        savedDevices = devices
    }
}

然后在DeviceListView中使用这个控制器:

struct DeviceListView: View {
    @StateObject var coreDataController = CoreDataController()
    @State var discoveredDevices: [BLEDevice] = []
    
    var body: some View {
        List {
            Section("已保存设备") {
                ForEach(coreDataController.savedDevices) { device in
                    Text(device.name ?? "未知设备")
                }
            }
            
            Section("新发现设备") {
                ForEach(discoveredDevices) { device in
                    Text(device.name)
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者YKWIBN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:23:09