SwiftUI 和具有 @Published 的组合 Observable 对象不断发布

Posted

技术标签:

【中文标题】SwiftUI 和具有 @Published 的组合 Observable 对象不断发布【英文标题】:SwiftUI and Combine Observable object having @Published is constantly publishing 【发布时间】:2019-12-06 22:50:51 【问题描述】:

我有这样的搜索栏视图模型,它对输入栏中的术语进行了搜索。然后它提出请求并分配给结果。

class SearchViewModel<T>: ObservableObject 

    @Published var searchTerm = ""
    @Published var results: [T] = []

    private var disposables = Set<AnyCancellable>()

    init() 
        $searchTerm
            .debounce(for: .seconds(1), scheduler: DispatchQueue.global())
            .flatMap  term in
                self.search(by: term)
            
            .print("searching")
            .assign(to: \.results, on: self)
            .store(in: &disposables)
    

    open func search(by term: String) -> AnyPublisher<[T], Never> 
        fatalError()
    

View 正在根据这个 $viewModel.results 检查是否在全屏模式下显示结果视图。

但尽管搜索通常被隐藏(如果用户没有点击按钮),但在这个发布者流中总是有一些事情发生

2019-12-06 23:45:09.810053+0100 CRM[1589:440623] [SwiftUI] Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
Dim drag (19.666656494140625, -1.6666717529296875)
searching: receive subscription: (FlatMap)
searching: request unlimited
Dim drag (42.33332824707031, -7.6666717529296875)
End dim drag: (56.33332824707031, -13.333328247070312)
searching: receive subscription: (FlatMap)
searching: request unlimited
searching: receive subscription: (FlatMap)
searching: request unlimited
searching: receive subscription: (FlatMap)
searching: request unlimited
Search button tapped!
searching: receive value: ([])
searching: receive value: ([])
searching: receive value: ([])
searching: receive value: ([])

这很奇怪,因为这应该只在输入到字段中的输入(术语)时触发。

我认为这里有问题。

更新!

重要的是,这个多个搜索流日志出现在控制台中,如果它使用条形按钮显示,则在汉堡菜单中拖动它,那么只有一次刷新。显示视图有点奇怪(或者更确切地说是用偏移量移动它会导致@Published var term 获得新的输入,而且我看到我的 List 内容正在刷新。

【问题讨论】:

【参考方案1】:

使用它不是很明显的测试环境,但我已经使用过滤器重建了如下帮助

.debounce(for: .seconds(1), scheduler: DispatchQueue.global())
.filter  !$0.isEmpty 

无论如何,在这样的用例中避​​免重新搜索相同的术语也是有用的。

【讨论】:

以上是关于SwiftUI 和具有 @Published 的组合 Observable 对象不断发布的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI,@Published 和 ForEach 没有更新我的视图

SwiftUI - 尽管使用了 @Published 和 @ObservedObject,但视图不会更新

SwiftUI:如何使用 UserDefaults 持久化 @Published 变量?

SwiftUI @Published 属性正在 DetailView 中更新

SwiftUI 如何将@Published 分配给另一个@Published

SwiftUI / Firebase:我可以使用@Published 向 Firebase 数据库发送和接收单个值吗?