让我们说我有一个这样的发布商:
NotificationCenter.default.publisher(for: NSNotification.Name.NSManagedObjectContextObjectsDidChange)
.map { notification in /.. do something ../}
我如何做到这一点,以便阻止发布者发布?
我可以将其设为trymap,然后引发错误。但是只能抛出异常以指示结果不足(在这种情况下,可以说是不相关的NSManagedObject更改),真是太奇怪了
答案 0 :(得分:2)
一种方法是使用filter
运算符。如果谓词为true,则会将原始输入传递给下游:
NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange)
.filter { note in note.object === myContext }
.map { note in /.. do something ../}
另一种方式(由bscothern在评论中提及)是使用compactMap
。您可以将输入转换为其他输出,或者如果想要抑制输出,则转换为nil:
NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange)
.compactMap { note in note.object === myContext ? myContext : nil }
.map { context in /.. do something ../}
答案 1 :(得分:0)
这里是基于可连接发布者的可行方法(该演示基于SwiftUI)。使用Xcode 11.3.1 / iOS 13.3进行了测试
struct TestConnectableNotification: View {
let publisher = NotificationCenter.default.publisher(for: Notification.Name("test")).makeConnectable()
@State private var text = "<none>"
@State private var subscriber: Cancellable? = nil
var body: some View {
VStack {
Text("Current: \(text)")
.onReceive(publisher) { _ in
let value = Int.random(in: 0..<10)
self.text = "\(value)"
}
Button(self.subscriber == nil ? "Enable" : "Disable") {
if nil == self.subscriber {
self.subscriber = self.publisher.connect()
} else {
self.subscriber?.cancel()
self.subscriber = nil
}
}
Button("Post") {
NotificationCenter.default.post(name: NSNotification.Name("test"), object: nil)
}
}
}
}
答案 2 :(得分:0)
另一种方法是使用flatMap
并发出Empty作为阻止程序(否则返回Just):
NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange)
.flatMap { input -> AnyPublisher<Notification, Never> in
if somethingOrOther {
return Just(input).eraseToAnyPublisher()
} else {
return Empty().eraseToAnyPublisher()
}
}