如何使用属性作为 FetchRequest 谓词的参数

Posted

技术标签:

【中文标题】如何使用属性作为 FetchRequest 谓词的参数【英文标题】:How do I use a property as an argument to a FetchRequest predicate 【发布时间】:2020-06-08 18:31:53 【问题描述】:

我试图在显示视图之前选择带有谓词的数据库项目并且需要传递一个属性,但我处于 catch-22 情况,因为该属性可能未初始化,产生消息:无法使用实例成员属性初始化程序中的“主题”;属性初始化器在“self”可用之前运行

struct ShowInfo: View

    @State var subject: Subject
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Info.entity(), sortDescriptors: [NSSortDescriptor(key: "title", ascending: true)],
                  predicate: NSPredicate(format: "subject.title == %@", $subject.title)
    ) var infos: FetchedResults<Info>
    @State var size = UIScreen.main.bounds.width / 3
    var body: some View
    
        List
            
                Text("Info").font(.system(size: 24)).foregroundColor(Color.green)
                ForEach(infos, id: \.infoid)
                 info in
                    ZStack
                    
                        if info.subject == self.subject.title
                        
                            NavigationLink(destination: EditInfoView(info: info))
                            
                                HStack
                                
                                    Text(info.title!).frame(width: 150, height: 40).background(Color.blue).foregroundColor(Color.white).cornerRadius(10)
                                    Text(info.value!)
                                
                            
                        
                    
                .onDelete(perform: deleteInfo)
        
    

【问题讨论】:

这能回答你的问题吗? ***.com/questions/57871088/… 我现在在初始化程序中遇到不同的错误。在显示的示例中, words 变量试图使用在初始化程序中获取的数据进行初始化,但初始化程序抱怨在离开初始化程序之前并未设置所有属性,这是真的。不确定我是否应该在此处或其他回复中发布我的持续问题。 【参考方案1】:

在SwiftUI View and @FetchRequest predicate with variable that can change 找到的答案基本上是正确的,但我发现结构内部出现的顺序很重要,以避免出现大量错误。

我修改了我的代码如下...

struct ShowInfo: View

    init (subject: Subject)
    
        self.subject = subject
        self.infoRequest = FetchRequest<Info>(entity: Info.entity(), sortDescriptors: [NSSortDescriptor(key: "title", ascending: true)],predicate: NSPredicate(format: "subject.title == %@", subject.title!))
    

    @Environment(\.managedObjectContext) var moc
    var subject: Subject
    var infoRequest: FetchRequest<Info>

    var infos: FetchedResults<Info>infoRequest.wrappedValue

这清除了所有错误并允许应用正常运行。当 init() 在变量声明之后时,我得到了与以前相同的错误以及其他错误。编译器似乎对什么已经初始化和什么没有初始化感到困惑。我不确定为什么问题 57871088 显示的示例适用于其他人,而我的需要重新安排声明。

【讨论】:

【参考方案2】:

我认为上述答案解决了我的问题,并且在这种情况下确实解决了,但在另一种观点中,相同的方法产生了错误,声称我没有初始化 init.xml 中的所有属性。经过大量试验,我发现如果我注释掉 @Environment 语句,所有这些错误都会消失。当然,这会为未定义的变量 moc 生成错误,所以我将代码注释掉以查看发生了什么,然后原始错误再次出现。编译器似乎很困惑。有谁知道解决这个问题的方法吗?

这是我现在正在使用的代码:

struct EditSubjectView: View

    init(subject: Subject)
    
        self.subject = subject
        self.formRequest = FetchRequest(entity: Field.entity(), sortDescriptors: [NSSortDescriptor(key: "sequence", ascending: true)], predicate: NSPredicate(format: "subjectid == %@", subject.subjectid!.description))
    

    @Binding var subject: Subject
    var formRequest: FetchRequest<Field>
    var fields : FetchedResults<Field>formRequest.wrappedValue

    @Environment(\.managedObjectContext) var moc

    var body: some View
    
        return VStack
            
                    HStack
                    
                            Text("Subject Title").padding(.leading)
                            //Spacer()
                    
                    TextField(subject.title!, text: Binding($subject.title)!)
                        .padding(.all)
                        .background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0))
                        .cornerRadius(15)
                    Spacer()
                    Button("Save")
                    

                        do
                        
                            try self.moc.save()
                        
                        catch
                        
                            print(error.localizedDescription)
                        

                    .frame(width: 150, height: 30).background(Color.red).foregroundColor(Color.white).cornerRadius(15.0)
            .padding()
    

【讨论】:

以上是关于如何使用属性作为 FetchRequest 谓词的参数的主要内容,如果未能解决你的问题,请参考以下文章

如何在Core Data中使用带有fetchRequest的谓词

如何根据用户输入使用新谓词重新运行@FetchRequest?

可可 iphone 核心数据谓词一对多 fetchrequest

将 UITextField 中的文本用于 fetchRequest 谓词

SwiftUI在FetchRequest中使用带有结构参数的谓词

当 UserDefaults 值更改 SwiftUI 时,@FetchRequest 谓词不会更新