Core data Swift UI-环境对象更改不会更新UI

Core data Swift UI-环境对象更改不会更新UI,core-data,swiftui,combine,Core Data,Swiftui,Combine,我正为下面的问题把头撞在桌子上。我有一个嵌套的数据存储(为了方便),通过@EnvironmentObject集成到视图中。如果我更改了数据存储中的某些内容(例如,在其中放入一个新对象,效果很好),UI不会更新 在控制台中,我还获得打印结果(“对象已更改”),这是由获取结果的更改引起的。但是UI只有在我重新启动应用程序后才会更新。这里怎么了 提前多谢 我的测试代码如下所示: 数据存储: import Foundation import Combine class DataStore : Obse

我正为下面的问题把头撞在桌子上。我有一个嵌套的数据存储(为了方便),通过@EnvironmentObject集成到视图中。如果我更改了数据存储中的某些内容(例如,在其中放入一个新对象,效果很好),UI不会更新

在控制台中,我还获得打印结果(“对象已更改”),这是由获取结果的更改引起的。但是UI只有在我重新启动应用程序后才会更新。这里怎么了

提前多谢

我的测试代码如下所示:

数据存储:

import Foundation
import Combine

class DataStore : ObservableObject{
    @Published var documents    = DocumentStore()
    @Published var attachments  = AttachmentStore()
}

附件存储

//
//  AttachmentStore.swift

import SwiftUI
import Combine
import CoreData

class AttachmentStore: NSObject, ObservableObject {


    // MARK: Private Properties
     let persistenceManager = PersistenceManager()

    private lazy var fetchedResultsController: NSFetchedResultsController<ManagedAttachment> = {
        let fetchRequest: NSFetchRequest<ManagedAttachment> = ManagedAttachment.fetchRequest()
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "dateCreated", ascending: false)]

        let fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: self.persistenceManager.managedObjectContext,
            sectionNameKeyPath: nil,
            cacheName: nil)
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }()

    private var attachment: [ManagedAttachment] {
        return fetchedResultsController.fetchedObjects ?? []
    }

    // MARK: Public Properties

    @Published var Items : [ManagedAttachment] = []

    public var allItems: [ManagedAttachment] {
        return self.attachment.filter {$0 == $0}
       }

    func setup(){
        self.Items = allItems
    }
    // MARK: Object Lifecycle

    override init() {
        super.init()
        fetchDocuments()
        setup()
    }

    // MARK: Public Methods

    public func allAttachments(for id: UUID) -> [ManagedAttachment]
    {
        let attachments = self.allItems.filter {$0.parentID == id}
        return attachments
    }

    public func create(attachment: Attachment) {
        ManagedAttachment.create(object: attachment, in: self.persistenceManager.managedObjectContext)
         saveChanges()
     }

    public func delete(attachment: ManagedAttachment){
        persistenceManager.managedObjectContext.delete(attachment)
        self.saveChanges()
    }

    public func update(){
        self.saveChanges()
    }


    // MARK: Private Methods

    private func fetchDocuments() {
        do {
            try fetchedResultsController.performFetch()
            dump(fetchedResultsController.sections)
        } catch {
            fatalError()
        }
    }

    private func saveChanges() {
        guard persistenceManager.managedObjectContext.hasChanges else { return }
        do {
            try persistenceManager.managedObjectContext.save()
            self.objectWillChange.send()
            print("Object Changed")
        } catch { fatalError() }
    }
}


extension AttachmentStore: NSFetchedResultsControllerDelegate {
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self.objectWillChange.send()
        print("Object Changed")
    }
}



好的,我这里的问题是我从附件存储发送了一个willChange,但不是从数据存储发送的,所以它没有更新。因此,解决方案是手动调用dataStore.objectWillChange.send()。谢谢大家!

看看这个答案:到底是什么不起作用?除了
setup()
@ribilynn外,我没有看到你在任何地方变异
项目
:非常感谢-我已经修复了它。我的问题是我从attachmentStore发送了一个willChange,但不是从datastore对象发送。谢谢!
import SwiftUI

struct TestView: View {
    @EnvironmentObject var data : DataStore

    var body: some View {
        VStack{
            Button(action: {
                self.data.attachments.create(attachment: Attachment(url: "Test"))
            }
            ) {
                Text("Add")
            }
            // Print the Items in the DataStore
            ForEach(data.attachments.Items, id:\.self){Item in
                Text(Item.url).font(.caption)
            }
        }

    }
}