.send()和.sink()似乎不再适用于Xcode 11 Beta 5中的PassthroughSubject [英] .send() and .sink() do not seem to work anymore for PassthroughSubject in Xcode 11 Beta 5
问题描述
在下面的代码中,当按下Button时,应该在控制台中打印"Test",但不是这样.该事件不是通过发布者发送的.知道Xcode 11 Beta 5中的PassthroughSubject发生了什么吗?(在Xcode 11 Beta 4中效果很好)
In the following code "Test" should be printed in the console when the Button is pressed, but it's not. The event is not send through the publisher. Any idea what happened with PassthroughSubject in Xcode 11 Beta 5 ? (in Xcode 11 Beta 4 it works well)
var body: some View {
let publisher = PassthroughSubject<String, Never>()
publisher.sink { (str) in
print(str)
}
return Button("OK") {
publisher.send("Test")
}
}
P.S.我知道按下按钮时还有其他打印字符串的方法,我只想展示一个简单的发送-接收示例
P.S. I know there are other ways to print a string when a button is pressed, I just wanna show a simple send-receive example
推荐答案
.sink()
返回 AnyCancellable
对象.您永远不应忽略它.从不这样做:
.sink()
returns an AnyCancellable
object. You should never ignored it. Never do this:
// never do this!
publisher.sink { ... }
// never do this!
let _ = publisher.sink { ... }
如果将其分配给变量,请确保它不是短命的.一旦取消了可取消对象的分配,订阅也将被取消.
And if you assign it to a variable, make sure it is not short lived. As soon as the cancellable object gets deallocated, the subscription will get cancelled too.
// if cancellable is deallocated, the subscription will get cancelled
let cancellable = publisher.sink { ... }
由于您要求在视图内使用 sink
,因此我将发布一种实现方法.但是,在视图内部,您可能应该改用 .onReceive()
.这样更简单.
Since you asked to use sink
inside a view, I'll post a way of doing it. However, inside a view, you should probably use .onReceive()
instead. It is way more simple.
使用接收器:
在视图中使用它时,您需要使用一个 @State
变量,以确保它在生成视图主体后仍然存在.
When using it inside a view, you need to use a @State
variable, to make sure it survives after the view body was generated.
DispatchQueue.main.async
是必需的,以避免在视图更新时修改状态.如果没有,则会出现运行时错误.
The DispatchQueue.main.async
is required, to avoid the state being modified while the view updates. You would get a runtime error if you didn't.
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()
Using .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)
}
}
}
这篇关于.send()和.sink()似乎不再适用于Xcode 11 Beta 5中的PassthroughSubject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!