【问题标题】:SwiftUI - explain difference in EnvironmentObject vs ObservableObject behavior on data refresh in ViewSwiftUI - 解释 View 中数据刷新时 EnvironmentObject 与 ObservableObject 行为的差异
【发布时间】:2021-03-11 18:37:25
【问题描述】:

我正在构建一个类似 Instagram 的应用程序,我注意到如果视图使用 ObservableObject (viewModel.posts) 从 Firestore 访问数据,则刷新数据时视图会闪烁。例如如果按赞按钮或添加了新帖子。

当视图使用 EnvironmentObject (session.posts) 从 Firestore 访问数据时,更新会顺利进行,不会出现任何闪烁。谁能解释为什么会这样?

这是 ObservableObject 的代码:

import SwiftUI
import Firebase

class PostViewModel: ObservableObject {
    @Published var posts = [Post]()
    
    init() {

        fetchPosts()
    }
    
    func fetchPosts() {

        COLLECTION_POSTS
            .order(by: "timeStamp", descending: true)
            .addSnapshotListener { querySnapshot, error in
                guard let documents = querySnapshot?.documents else {
                    print("Error fetching Request documents: \(error!)")
                    return
                }
                self.posts.removeAll(keepingCapacity: false)

                for doc in documents {
                    let mappedDoc = Post(dictionary: doc.data())
                    self.posts.append((mappedDoc!))
                }
                return
            }
    }
}

这里是 EnvironmentObject 的代码:

import Foundation
import Firebase

class FirebaseSession: ObservableObject {
    @Published var posts: [Post] = []
}

extension FirebaseSession {

    func listenerPosts() {
        
        COLLECTION_POSTS
            .order(by: "timeStamp", descending: true)
            .addSnapshotListener { querySnapshot, error in
                guard let documents = querySnapshot?.documents else {
                    print("Error fetching Request documents: \(error!)")
                    return
                }
                self.posts.removeAll(keepingCapacity: false)
                
                for doc in documents {
                    let mappedDoc = Post(dictionary: doc.data())
                    self.posts.append((mappedDoc!))
                }
                return
            }
    }
}

【问题讨论】:

  • 当您在视图中使用 ObservableObject 时,您是使用它作为@ObservedObject 还是@StateObject?
  • 您是如何设法将@Published 放入扩展程序的?你确定你没有遗漏任何重要的代码吗?
  • @jnpdx,我在视图中使用的是 ObservedObject,而不是 StateObject。
  • @pawello2222 - 你是对的,我已经在 FirebaseSession 类中发布了。
  • 我认为你是对的,似乎 ObservableObject 的视图在每次发生变化时都在运行init(),这意味着在检测到变化后视图被清除并重绘。我发现这两篇解释差异的文章希望它们可以帮助您理解article1article2

标签: google-cloud-firestore swiftui


【解决方案1】:

已解决:使用 ObservedObject 重绘 View,使用 StateObject 解决了问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2020-08-05
    • 2021-06-05
    • 2020-05-17
    相关资源
    最近更新 更多