在我的应用程序中,我有两个CoreData实体,它们之间存在一对多的关系:People-> Subject
我正在使用列表渲染人物的名字

struct PeopleListView: View {
    @FetchRequest(
            entity: People.entity(),
            sortDescriptors: [NSSortDescriptor(keyPath: \People.updatedAt, ascending: false)]
        ) var people: FetchedResults<People>

    var body: some View {
        NavigationView {
            List {
                ForEach(people) { person in
                    NavigationLink(destination: PersonView(person: person)) {
                        Text(person.name)
                    }
                }
            }
        }

    }
然后在PersonView上:
struct PersonView: View {
    var person: Person

    @Environment(\.managedObjectContext) var context;

    var body: some View {
        List {
            Button(action: {
                self.person.subjects.insert(Subject(context: self.context))
            }, label: { Text("Add Subject") })
            ForEach(Array(person.subjects)) { subject in
                Text(subject.name)
            }
        }


    }
}
当我点击“添加主题”按钮时,会收到以下警告:
[TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: <_TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView: 0x7f8e0e822800; baseClass = UITableView; frame = (0 0; 414 896); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x600003f0ed30>; layer = <CALayer: 0x60000315a720>; contentOffset: {0, -140}; contentSize: {414, 748}; adjustedContentInset: {140, 0, 34, 0}; dataSource: <_TtGC7SwiftUIP13$7fff2c9c8ad419ListCoreCoordinatorGVS_20SystemListDataSourceOs5Never_GOS_19SelectionManagerBoxS2___: 0x7f8e0cc0e070>>
我认为我的问题实际上是,一旦我给一个人添加了一个主题,当我使用PeopleListView时,FetchRequest就会“得到通知”并重新绘制PersonView
我真的很感谢为这个问题提供一个适当的解决方案,我想应该有一种方法可以对FetchRequest说不听关系上的变化,但是我找不到。
我还使用了其他解决方案,例如代理主题列表,并且仅在返回PeopleListView时才“注入”它们,但这听起来很糟糕。
谢谢!

最佳答案

如果仍然需要在获取主要实体期间避免获取关系,则可以使用结合使用SwiftUI NSFetchRequest的自定义FetchRequest的方法。
经过Xcode 12 / iOS 14测试

struct PeopleListView: View {

    @FetchRequest
    var people: FetchedResults<People>

    init() {
        let request: NSFetchRequest<People> = People.fetchRequest()
        request.sortDescriptors = []
        request.includesSubentities = false             // << here !!

        _people = FetchRequest(fetchRequest: request)
    }

    // ... other code

关于ios - 如何防止FetchRequest观察关系的变化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63533165/

10-10 06:32