首页 > 解决方案 > 防止立即调用 sink 的 receiveValue 闭包

问题描述

考虑以下代码(您可以直接将其 c&p 到 Playground 中):

class Foo: ObservableObject {
    @Published var bar = "bar"
}

let foo = Foo()
let someSubscriber = foo.$bar
    .sink { value in
        print("value is \(value)")
    }

尽管 Foo 刚刚被初始化一次并且它的成员bar从未改变过,但是 sink 会receiveValue立即执行它的闭包。有什么方法可以防止这种初始呼叫的发生,例如,有没有我可能忽略的操作员?

标签: swiftswiftuicombine

解决方案


您可以使用dropFirst运算符。没有参数,它只删除上游的第一个输出。

let someSubscriber = foo.$bar
    .dropFirst()
    .sink { value in
        print("value is \(value)")
    }

为了解决评论中提出的问题:

的每个实现都Publisher可以决定如何处理每个新订阅者。这是一个政策决定,通常不是设计缺陷。不同Publisher的s做出不同的决定。这里有些例子:

  • PassthroughSubject不会立即发布任何内容。
  • CurrentValueSubject立即发布其当前值。
  • NSObject.KeyValueObservingPublisher当且仅当它是使用.initial选项创建时,立即发布观察到的属性的当前值。
  • Published.Publisher(这是您为@Published属性获得的类型)立即发布属性的当前值。

推荐阅读