【问题标题】:Accessing property is not possible无法访问财产
【发布时间】:2021-08-16 15:03:28
【问题描述】:

我想在MainView 中显示一个单独的SubjectView

SubjectViewsubject 上的属性topics 不可访问。

我该怎么办?谢谢。


更新

ForEach(subject.topics, id: \.self) { topic in
    Text(topic.title)
}

...可能是有问题的部分。


文件:SubjectView

import SwiftUI

struct SubjectView: View {
    @State var subject: Subject
    
    var body: some View {
        List {
            ForEach(subject.topics, id: \.self) { topic in
                Text(topic.title)
            }
        }
    }
}

文件MainView

import SwiftUI

struct MainView: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    
    @FetchRequest(entity: Subject.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Subject.name, ascending: true)]) var subjects: FetchedResults<Subject>
    
    @State var subjectName: String = ""
    
    var body: some View {
        NavigationView {
            Form {
                List {
                    ForEach(subjects, id: \.self) { subject in
                        NavigationLink(
                            destination: SubjectView(subject: subject),
                            label: {
                                Text(subject.name ?? "-")
                            })
                    }
                }
            }
            .navigationTitle("Schulfächer")
        }
    }
}

Screenshot of the Subject entity

SubjectView:var body: some View 处的错误为:

Failed to produce diagnostic for expression; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project

【问题讨论】:

  • 你应该显示Subject
  • 主题由 XCode 创建
  • 不相关但@State in SubjectView 没有意义。 @State 用于值类型,@StateObject 用于引用类型。但由于这个对象实际上不是 真相的来源 并且无论如何都是引用类型,所以只需声明 let subject: Subject
  • @vadian,谢谢!

标签: swift core-data swiftui


【解决方案1】:

ForEach 的集合类型必须符合RandomAccessCollectiontopics 不是因为它是(NS)Set

一个简单的解决方案是将sort Set 变成Array。或者显式创建一个数组,该行假定topics 是原生Swift Set&lt;Topic&gt;

Array(subject.topics)

注意:不要随意使用\.self。确定一个唯一的属性和/或采用Identifiable。例如,您可以使用唯一的 NSManagedObject 实例的 NSManagedObjectID

【讨论】:

    【解决方案2】:
    @State var subject: Subject
    

    SubjectView 中应该是

    @ObservedObject var subject: Subject
    

    https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app

    @StateObject 用于初始化ObservableObjects

    至于你的话题

    ForEach((subject.topics.allObjects as? [Topic]) ?? [], id: \.self) { topic in
    

    应该有效

    【讨论】:

    • 视图似乎没有修改核心数据记录。所以@ObservedObject 太过分了。
    • 也许我假设会有更多,因为用户有一个循环。它还会在其他地方进行更改时更新视图
    • 另一个问题:我的数据没有持久化。你知道为什么吗?谢谢!
    • 坚持?您的代码中没有任何内容显示持久性。你在存钱吗?
    • managedObjectContext.save() ?一些 Button 会导致这种情况。