SwiftUI 中的 FetchRequest 包装值:EXC_BAD_INSTRUCTION

Jop*_*laz 5 core-data nsfetchrequest swift swiftui

我正在尝试TrainingSessionHistory在我的 SwiftUI 视图之一中对我的(核心数据对象)进行简单的获取请求,但得到了Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

struct TrainingHistoryView: View {

var trainingSession  : TrainingSession

init(trainingSession : TrainingSession) {
    self.trainingSession = trainingSession

    let fetchRequest = FetchRequest(fetchRequest: TrainingSessionHistory.getBy(nb: 2, myTrainingSession: self.trainingSession))
    print(fetchRequest.wrappedValue) // -> crash this EXC_BAD_INSTRUCTION

}
Run Code Online (Sandbox Code Playgroud)

TrainingSessionHistoryExtension : 创建获取请求

static func getBy(nb : Int, myTrainingSession : TrainingSession) -> NSFetchRequest<TrainingSessionHistory>{
    let request:NSFetchRequest<TrainingSessionHistory> = TrainingSessionHistory.fetchRequest() as!    NSFetchRequest<TrainingSessionHistory>

    //request.predicate = NSPredicate(format: "trainingSession == %@", myTrainingSession)
    request.fetchLimit = nb

    let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)

    request.sortDescriptors = [sortDescriptor]

    return request
}
Run Code Online (Sandbox Code Playgroud)

我不明白请求中发生了什么不好的事情:

po 调试

编辑:修复

替换为

let req = TrainingSessionHistory.getBy(nb: 2, myTrainingSession: self.trainingSession)
        self.alternativeContext.performAndWait {
            do {
                let result = try req.execute()
                print(result)
            }catch {
                print(error)
            }
        }
Run Code Online (Sandbox Code Playgroud)

alternativeContext在委托中定义如下所示:

lazy var alternativeContext: NSManagedObjectContext = {
        let context = persistentContainer.newBackgroundContext()
        return context
}()
Run Code Online (Sandbox Code Playgroud)

感谢/sf/answers/3945183231/

一切正常,但仍然不明白为什么“FetchRequest.wrappedValue()”方法不起作用。

mal*_*hal 0

因为在 init 中,FetchRequest 还没有从环境中获取所需的托管对象上下文。只有在调用 body 之前更新它时才会出现这种情况。

改成:

struct TrainingHistoryView : View {

    var trainingSession : TrainingSession
    @FetchRequest var history : FetchedResults<TrainingSessionHistory>

    init(trainingSession : TrainingSession) {
        self.trainingSession = trainingSession
        _history = FetchRequest(fetchRequest: TrainingSessionHistory.getBy(nb: 2, myTrainingSession: trainingSession))
    }

    var body: some View {
        // history is now valid
    }
}
Run Code Online (Sandbox Code Playgroud)