Skip to content

Instantly share code, notes, and snippets.

@calvingit
Created November 4, 2023 11:34
Show Gist options
  • Save calvingit/b9d899a2d6a966f7a9296ad4a65a9695 to your computer and use it in GitHub Desktop.
Save calvingit/b9d899a2d6a966f7a9296ad4a65a9695 to your computer and use it in GitHub Desktop.
广播事件分发器
import Foundation
// 事件
@objcMembers
class EPEvent: NSObject {
/// 事件 id,唯一
private(set) var id: String = ""
/// 对象参数
private(set) var object: Any?
/// 序列化参数
private(set) var params: [String: Any]?
private override init() {
super.init()
}
convenience init(id: String, object: Any? = nil, params: [String: Any]? = nil) {
self.init()
self.id = id
self.object = object
self.params = params
}
/// 以下方法暴露给 Objective-C
@objc(eventWithId:)
static func event(_ id: String) -> EPEvent {
EPEvent(id: id, params: nil)
}
@objc(eventWithId:params:)
static func event(_ id: String, params: [String: Any]?) -> EPEvent {
EPEvent(id: id, params: params)
}
@objc(eventWithId:object:)
static func event(_ id: String, object: Any?) -> EPEvent {
EPEvent(id: id, object: object)
}
}
/// EPEventDisposable 对象释放时取消订阅事件,由 subscribeSingleEvent(_:completion:) 方法返回
@objcMembers
class EPEventDisposable: NSObject {
private var disposeAction: (() -> Void)?
init(disposeAction: @escaping () -> Void) {
self.disposeAction = disposeAction
}
private override init() {
super.init()
}
deinit {
disposeAction?()
}
}
// 事件订阅协议
@objc protocol EPEventSubscriber {
func receiveEvent(_ event: EPEvent)
}
// 事件分发器
@objc class EventPublisher: NSObject {
@objc static let shared = EventPublisher()
private var subscribers: [EPEventSubscriber] = []
private var singleSubscribers: [String: (EPEvent) -> Void] = [:]
private let eventQueue = DispatchQueue(label: "com.EventPublisher.eventQueue", attributes: .concurrent)
private override init() {
super.init()
}
// 订阅所有事件
@objc func subscribe(_ subscriber: EPEventSubscriber) {
eventQueue.async(flags: .barrier) {
self.subscribers.append(subscriber)
print("\(self.subscribers)")
}
}
// 订阅单个事件
@objc func subscribeSingleEvent(_ eventId: String, completion: @escaping (EPEvent) -> Void) -> EPEventDisposable {
let disposable = EPEventDisposable { [weak self] in
self?.unsubscribeSingleEvent(eventId)
}
eventQueue.async(flags: .barrier) {
self.singleSubscribers[eventId] = completion
}
return disposable
}
// 取消订阅单个事件
private func unsubscribeSingleEvent(_ eventId: String) {
eventQueue.async(flags: .barrier) {
self.singleSubscribers.removeValue(forKey: eventId)
}
}
// Method to unsubscribe from events
@objc func unsubscribe(_ subscriber: EPEventSubscriber) {
eventQueue.async(flags: .barrier) {
self.subscribers.removeAll { $0 === subscriber }
print("\(self.subscribers)")
}
}
// 发布事件给所有订阅者
@objc func publish(_ event: EPEvent) {
eventQueue.async {
for subscriber in self.subscribers {
NSLog("\(subscriber)")
DispatchQueue.main.async {
subscriber.receiveEvent(event)
}
}
if let completion = self.singleSubscribers[event.id] {
DispatchQueue.main.async {
completion(event)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment