.send()和.sink()似乎不再适用于Xcode 11 Beta 5中的PassthroughSubject [英] .send() and .sink() do not seem to work anymore for PassthroughSubject in Xcode 11 Beta 5

查看:48
本文介绍了.send()和.sink()似乎不再适用于Xcode 11 Beta 5中的PassthroughSubject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,当按下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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆