1. 程式人生 > >Swift自定義事件分發

Swift自定義事件分發

Swift自帶有Notification,可以作為事件分發用,下面是自定義的一種事件分發,使用觀察者模式

/// 自定義訊息分發類,為單例
/// 注意:新增偵聽後,一定要移除
public final class Messager{
    
    private static var _shared:Messager?
    
    public static var shared:Messager!{
        get{
            if _shared == nil {
                _shared = Messager()
                return _shared!
            }
            return _shared!
        }
    }
    
    private init(){}
    
    
    /// key為事件名,value為元組(target: 物件, call: 方法)
    private var evts = Dictionary<String,[(target:AnyObject?,call:(Any)->Void)]>()
    
    
    /// 新增偵聽
    ///
    /// - Parameters:
    ///   - event: 事件名
    ///   - target: 物件
    ///   - callBack: 回撥方法
    public func addListener(_ event:String!,target:AnyObject?,callBack:@escaping (Any)->Void )
    {
        var list = evts[event]
        if list == nil {
            list = []
        }
        list?.append((target:target,call:callBack))
        evts[event] = list
    }
    
    
    /// 通過事件名刪除偵聽
    ///
    /// - Parameter event: 事件名
    public func removeListener(_ event:String!)->Void
    {
        if evts[event] != nil
        {
            evts.removeValue(forKey: event)
        }
    }
    
    
    /// 通過事件名和物件移除偵聽
    ///
    /// - Parameters:
    ///   - event: 事件名
    ///   - target: 物件
    public func removeListener(_ event:String! , target: AnyObject? )
    {
        var list = evts[event]
        if list != nil {
            for (i,element) in list!.enumerated() {
                if target === element.target {
                    list?.remove(at: i)
                    if list?.count == 0 {
                        self.evts.removeValue(forKey: event)
                    }
                    break
                }
            }
        }
    }
    
    
    /// 丟擲事件
    ///
    /// - Parameters:
    ///   - event: 事件名
    ///   - data: 資料
    public func dispatch(_ event:String!, data:Any?)
    {
        let list = evts[event]
        if list != nil
        {
            for element in list! {
                element.call(data as Any)
            }
        }
    }
    
    
    /// 清除所有偵聽
    public func clearAll()->Void{
        evts.removeAll()
    }
}

//測試
Messager.shared.addListener("EVENT_OK",target:nil,callBack: { (data) in
    print( data as! Int )
})
//Messager.shared.addListener("EVENT_ERROR",target:nil,callBack: { (data) in
//    print("Error: \(data as! Int)" )
//})

Messager.shared.dispatch("EVENT_OK", data: 3)
Messager.shared.removeListener("EVENT_OK",target:nil)
Messager.shared.dispatch("EVENT_OK", data: 3)
Messager.shared.dispatch("EVENT_ERROR", data:5)

可惜沒找到如何判斷兩個方法相等,不然可以通過事件名和方法來移除偵聽