简体   繁体   English

设置时调用一次 Swift Combine 接收器?

[英]Swift Combine sink called once at setup?

I am setting up a sink like so:我正在设置一个像这样的sink

    name.publisher
        .removeDuplicates()
        .receive(on: RunLoop.main)
        .sink { [weak self] config in
            guard let self = self else { return }

            // this closure gets called right away at setup even though the @Published property `name` was already setup and did not change
            
        }.store(in: &subscribers)

The property is declared like so in an observable object:该属性在可观察对象中声明如下:

 @Published var name:String = ""

So, I'm obviously missing something here.所以,我显然在这里遗漏了一些东西。 Why is sink called once at setup even though name did not change?为什么即使name没有更改,也会在设置时调用一次接收器? I can avoid this behavior by using the dropFirst() operator but, I'd like to understand why the closure is always called once immediately after setup?我可以通过使用dropFirst()运算符来避免这种行为,但是,我想了解为什么闭包总是在设置后立即调用一次?

Why is that?这是为什么?

Here's a playground that uses debugPrint to show you what you get from name.publisher :这是一个使用debugPrint向您展示从name.publisher获得的内容的游乐场:

import UIKit
import Combine

//Holds the score
class ViewModel : ObservableObject {
    @Published var name = "0"
}

let viewModel = ViewModel()
debugPrint(viewModel.name.publisher)

What you get is你得到的是

Combine.Publishers.Sequence<Swift.String, Swift.Never>(sequence: "0")

So you get a sequence publisher that has a single item, "0".所以你得到一个序列发布者,它有一个项目,“0”。 It will publish that value once and the sequence will end.它将发布该值一次,序列将结束。 Each time a subscriber attaches to that sequence it will get all the items in the sequence (there's only one) and the end.每次订阅者附加到该序列时,它将获得序列中的所有项目(只有一个)和结束。

This is probably not what you want.这可能不是你想要的。

Instead I think you want to use $name to access the published property:相反,我认为您想使用$name来访问已发布的属性:

import UIKit
import Combine

//Holds the score
class ViewModel : ObservableObject {
    @Published var name = "0"
}

let viewModel = ViewModel()
let subscription = viewModel.$name.sink { print($0) }
viewModel.name = "Alex"

When you subscribe to the published property you will still get a posted event that is the current value of the property .当您订阅已发布的属性时,您仍将获得一个已发布的事件,该事件是该属性的当前值 However, by using $name you are attaching to a stream that will send you the current value on subscription AND each subsequent value.但是,通过使用$name您将附加到一个流,该流将向您发送订阅的当前值和每个后续值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM