.send() 和 .sink() 似乎不再适用于 Xcode 11 Beta 5 中的 PassthroughSubject
.send() and .sink() do not seem to work anymore for PassthroughSubject in Xcode 11 Beta 5
在下面的代码中,"Test" 应该在按下 Button 时在控制台中打印出来,但事实并非如此。该事件不通过发布者发送。
知道 Xcode 11 Beta 5 中的 PassthroughSubject 发生了什么吗?
(在 Xcode 11 Beta 4 中运行良好)
var body: some View {
let publisher = PassthroughSubject<String, Never>()
publisher.sink { (str) in
print(str)
}
return Button("OK") {
publisher.send("Test")
}
}
P.S。我知道还有其他方法可以在按下按钮时打印字符串,我只想展示一个简单的发送-接收示例
.sink()
returns 一个 AnyCancellable
对象。你不应该忽视它。 永远不要这样做:
// never do this!
publisher.sink { ... }
// never do this!
let _ = publisher.sink { ... }
如果您将它分配给一个变量,请确保它不是短暂存在的。一旦取消分配可取消对象,订阅也将被取消。
// if cancellable is deallocated, the subscription will get cancelled
let cancellable = publisher.sink { ... }
既然您要求在视图中使用 sink
,我将 post 提供一种方法。但是,在视图中,您可能应该改用 .onReceive()
。它更简单。
使用接收器:
在视图中使用它时,您需要使用一个 @State
变量,以确保它在视图主体生成后仍然存在。
DispatchQueue.main.async
是必需的,以避免在视图更新时修改状态。否则会出现运行时错误。
struct ContentView: View {
@State var cancellable: AnyCancellable? = nil
var body: some View {
let publisher = PassthroughSubject<String, Never>()
DispatchQueue.main.async {
self.cancellable = publisher.sink { (str) in
print(str)
}
}
return Button("OK") {
publisher.send("Test")
}
}
}
使用.onReceive()
struct ContentView: View {
var body: some View {
let publisher = PassthroughSubject<String, Never>()
return Button("OK") {
publisher.send("Test")
}
.onReceive(publisher) { str in
print(str)
}
}
}
订阅接收器时缺少 .store。
您可以使用 .onReceive,但您的代码没有接收值,因为您需要添加 .store(in: &subscription)
var body: some View {
var subscription = Set<AnyCancellable>()
let publisher = PassthroughSubject<String, Never>()
publisher.sink { (str) in
print(str)
}.store(in: &subscription)
return Button("OK") {
publisher.send("Test")
}
}
在下面的代码中,"Test" 应该在按下 Button 时在控制台中打印出来,但事实并非如此。该事件不通过发布者发送。 知道 Xcode 11 Beta 5 中的 PassthroughSubject 发生了什么吗? (在 Xcode 11 Beta 4 中运行良好)
var body: some View {
let publisher = PassthroughSubject<String, Never>()
publisher.sink { (str) in
print(str)
}
return Button("OK") {
publisher.send("Test")
}
}
P.S。我知道还有其他方法可以在按下按钮时打印字符串,我只想展示一个简单的发送-接收示例
.sink()
returns 一个 AnyCancellable
对象。你不应该忽视它。 永远不要这样做:
// never do this!
publisher.sink { ... }
// never do this!
let _ = publisher.sink { ... }
如果您将它分配给一个变量,请确保它不是短暂存在的。一旦取消分配可取消对象,订阅也将被取消。
// if cancellable is deallocated, the subscription will get cancelled
let cancellable = publisher.sink { ... }
既然您要求在视图中使用 sink
,我将 post 提供一种方法。但是,在视图中,您可能应该改用 .onReceive()
。它更简单。
使用接收器:
在视图中使用它时,您需要使用一个 @State
变量,以确保它在视图主体生成后仍然存在。
DispatchQueue.main.async
是必需的,以避免在视图更新时修改状态。否则会出现运行时错误。
struct ContentView: View {
@State var cancellable: AnyCancellable? = nil
var body: some View {
let publisher = PassthroughSubject<String, Never>()
DispatchQueue.main.async {
self.cancellable = publisher.sink { (str) in
print(str)
}
}
return Button("OK") {
publisher.send("Test")
}
}
}
使用.onReceive()
struct ContentView: View {
var body: some View {
let publisher = PassthroughSubject<String, Never>()
return Button("OK") {
publisher.send("Test")
}
.onReceive(publisher) { str in
print(str)
}
}
}
订阅接收器时缺少 .store。 您可以使用 .onReceive,但您的代码没有接收值,因为您需要添加 .store(in: &subscription)
var body: some View {
var subscription = Set<AnyCancellable>()
let publisher = PassthroughSubject<String, Never>()
publisher.sink { (str) in
print(str)
}.store(in: &subscription)
return Button("OK") {
publisher.send("Test")
}
}