订阅发布发布者时无法获得最新值

Cannot get latest value when subscribing to the emitting Publisher

我有一个侦听器,它在用户登录和注销时 registered/deregistered。我有类似于以下代码的东西,

import Foundation
import Combine

class X : ObservableObject {
    @Published var data: String? = nil
    
    func setData() {
        data = "DATA"
    }
}

let x = X()
var store = Set<AnyCancellable>()
x.$data.sink { v1 in  // I need to add .receive(on:) here
    print(v1)
    if v1 != nil {
        x.$data.sink { v2 in
            print(v2) // Why is this nil
        }.store(in: &store)
    }
}.store(in: &store)

x.setData()

我以为 v2 会是 "DATA",但事实并非如此。我需要在外部订阅中执行 .receive(on: DispatchQueue.main) 以使它们都接收“之后”状态。

我的工作理论是在调用所有处理程序后不会写入该值,因为我不知道如何验证它,更不用说它是否正确了。

这里为什么需要receive(on:)

I know I could've used flatMap, but I didn't use it because I my state is delivered way too late, and I need to unsubscribe to the inner mapped publisher before the sign out code runs to avoid permission issues.

这里发生的是一个非常微妙的行为。

表达式 x.$data 的计算结果为 Published.Publisher。当你订阅一个 Published.Publisher 时,它立即发布它的当前值,然后每次 Published 属性 收到一个新值,发布者在 之前发布新值 新值存储在 属性.

此行为记录在 Published reference:

When the property changes, publishing occurs in the property’s willSet block, meaning subscribers receive the new value before it’s actually set on the property.

这意味着当您调用 x.setData() 时,外部订阅在 v1 中接收到新值 ("DATA"),但此时 x.data 的计算结果仍为 nil。当你创建对 x.$data 的内部订阅时,它会立即发布它的 当前存储的值 ,它仍然是 nil.