来自自定义 Combine 订阅者的商店订阅?

Store subscription from custom Combine subscriber?

根据 swift 组合文档,将订阅者连接到发布者的正确方法是使用发布者 subscribe<S>(S) 协议扩展方法。然后发布者创建一个订阅并将该订阅传递给订阅者。到目前为止一切都很好。

我似乎无法弄清楚如何获得对该订阅的访问权限并将其保留在调用代码中。 sink() 如何实施才能 return 该订阅?除非我弄错了,否则订阅负责保留其订阅者,这意味着我无法在订阅者中存储对订阅的引用。由于 Subscription 不受 class 约束,因此它不会很弱。

可取消项保留订阅(或者可能订阅。记住订阅是可取消项。)因此,当您保留可取消项时,您将保留订阅。

下面是 sink 可能 实施方式的示例

import Combine
import Foundation

extension Publisher {
    func mockSink(
        receiveValue: @escaping (Output) -> Void,
        receiveCompletion: @escaping (Subscribers.Completion<Failure>) -> Void) -> AnyCancellable {

            var result : AnyCancellable!
            let anySubscriber = AnySubscriber(
                receiveSubscription: { subscription in
                    subscription.request(.unlimited)
                    result = AnyCancellable({subscription.cancel()})
                },
                receiveValue: { (value : Output) in receiveValue(value); return .unlimited},
                receiveCompletion: receiveCompletion)

            subscribe(anySubscriber)
            return result
        }
}

var subscriptions = Set<AnyCancellable>()
["one", "two", "three"].publisher
    .mockSink(receiveValue: {debugPrint([=10=])}, receiveCompletion: {debugPrint([=10=])})
    .store(in: &subscriptions)

如您所见,return 和 AnyCancellable 的能力源于 AnySubscriber 的魔力,return 是它在闭包中的订阅。 AnySubscriber 是实现自定义 Publishers 时的便捷工具,如果您想实现自己的 Subscriber 类型,它可能会有所帮助。但基本上 Subscriber 仅在设计时公开订阅。