首页 > 解决方案 > Swift组合自定义发布者:存储对订阅者数组的引用?

问题描述

我正在尝试编写一个自定义组合,它将通过水龙头Publisher发送分贝和时间戳。AVAudioEngine在浏览了大量教程和 WWDC 视频之后,我仍然找不到一个示例来说明 a 如何Publisher跟踪Subscriber订阅它的 s。

public typealias AudioVolume = Double

public struct AudioVolumePublisher: Publisher {
    public typealias Output = AudioVolume
    public typealias Failure = Error
}

public class AudioVolumeSubscription<S: Subscriber>: NSObject, Subscription {
    private var subscriber: S?
    public var combineIdentifier = CombineIdentifier()

    public init(for subscriber: S) {
        self.subscriber = subscriber
    }

    public func request(_ demand: Subscribers.Demand) {
        ...
    }

    public func cancel() {
        subscriber = nil
    }
}

我假设AudioVolumePublisher应该存储其活动订阅者的列表,但添加一个属性

var subscribers = [S]()

不会编译,因为Subscriber有关联的类型。这甚至是处理Subscribers 的正确方法吗?如果是,那么存储它们的最佳方法是什么?类型擦除是我唯一实用的选择吗?

标签: swiftcombine

解决方案


您可以使用CurrentValueSubject或来实现您的目标PassthroughSubject

假设这是您发送的形状:

struct AudioVolume {
  let decimal: Decimal
  let timestamp: TimeStamp
}

实例化主题

let audioPublisher = PassthroughSubject<AudioVolume, Never>()

每当您需要发布新值时:

let audioVolume = AudioVolume(....)
audioPublisher.send(audioVolume)

每当您需要订阅发布者时:

audioPublisher
  .sink { audioVolume in
    // do something with audioVolume
  }
  .store(in: &cancellables) // retain the subscription in cancellables as long as you want to remain subscribed

推荐阅读