如何使用Combine和Swift创建和发出自定义事件



我有一个类,我想由多个订阅者订阅。我怎样才能实现这样的东西(被认为是伪代码(?是否可以在不手动实现Subscription、Publisher的情况下轻松实现此类事件?

简而言之,它应该升级为Delegate模式。它可以潜在地处理Void事件。仅仅创建类型为([Item],[Item](的Published属性是不可行的,因为具有相同重复数据的事件可以逐个发送。

class SomeObservedClass: ObservableObject {
//???
}
//We will have multiple listeners like this
class SomeListener1 {
@Published var observedClass: SomeObservedClass

init() {
observedClass = .init()

//Maybe something like this
observedClass
.publisher(for: .listChanged)
.sink { (addingItems: [Item], removingItems: [Item]) in
//Processing data
}
.store(in: &cancellable)

//Or something like this maybe
observedClass
.onReceive(.listChanged) { (addingItems: [Item], removingItems: [Item]) in
//Processing data
}
}
}

以下是使用PassthroughSubject的解决方案。现在是我能生产的最短、最干净的。经过多个订阅者的测试,工作正常。

class MainClass {
private let sequenceManager: SequenceManager = .init()
private var bucket: Set<AnyCancellable> = []

func subscribeMe() {
//Here is how we use our publisher
sequenceManager
.publisher(for: .onSequenceUpdate)
.receive(on: DispatchQueue.main) //Optionally
.sink { (addingItems, removingItems) in
//Handle new data here
}
.store(in: &bucket)
}
}
//Object we want to publish its changes
class SequenceManager {
private let sequencePublisher = UpdatedSequencePublisher()

private func didUpdate(addingItems: [String], removingItems: [String]) {
//Here we publish changes
sequencePublisher.publish(adding: addingItems, removing: removingItems)
}
}
//Our publisher stuff
extension SequenceManager {
struct UpdatedSequencePublisher: Publisher {
typealias Output = (adding: [String], removing: [String])
typealias Failure = Never
private let passThroughSubject = PassthroughSubject<Output, Failure>()

func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
passThroughSubject.receive(subscriber: subscriber)
}

func publish(adding: [String], removing: [String]) {
passThroughSubject.send((adding, removing))
}
}

func publisher(for event: Event) -> UpdatedSequencePublisher {
switch event {
case .onSequenceUpdate:
return sequencePublisher
}
}

enum Event {
case onSequenceUpdate
}
}

最新更新