SwiftUI - 解释 View 中数据刷新时 EnvironmentObject 与 ObservableObject 行为的差异
Posted
技术标签:
【中文标题】SwiftUI - 解释 View 中数据刷新时 EnvironmentObject 与 ObservableObject 行为的差异【英文标题】:SwiftUI - explain difference in EnvironmentObject vs ObservableObject behavior on data refresh in View 【发布时间】: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
【参考方案1】:
已解决:使用 ObservedObject 重绘 View,使用 StateObject 解决了问题
【讨论】:
以上是关于SwiftUI - 解释 View 中数据刷新时 EnvironmentObject 与 ObservableObject 行为的差异的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 后台刷新多个 Section 导致 global index in collection view 与实际不匹配问题的解决
SwiftUI 如何快速识别视图(View)界面的刷新是由哪个状态的改变导致的?
SwiftUI 如何快速识别视图(View)界面的刷新是由哪个状态的改变导致的?