Swift 路由機制設計

設計模式

APP設計模式多種多樣,從最初的MVC到MVVM,再到MVP,VIPER等。愈來愈多的設計模式被開發出來並得以應用,但不論咱們用到哪一種設計模式,只須要記住高內聚、低耦合那邊是好的設計模式。在這裏筆者整理了一份demo以幫助你們更好的理解Swift版路由機制的設計html

APP路由機制出現

筆者瞭解到最開始分享路由機制的文章是由蘑菇街團隊提供連接,其利用url註冊來進行界面推出和傳值。隨後某位大神吐槽其機制有問題連接。在這裏筆者也開始思考過這個問題,並從他們的思路中得出了適合本身的路由機制設計。路由機制原理、優勢等信息網上有太多的資料可供參考,筆者不在這裏贅述。下面就爲你們介紹筆者的路由機制設計方式git

路由機制設計原理

筆者以爲路由機制的設計主要涉及到兩點問題github

  • 推出界面(肯定的目標控制器)
  • 數據傳輸(正向傳值和反向傳值)

推出界面

界面推出筆者選擇了最爲簡單直接的一種方式,直接經過類名肯定須要推出的控制器界面。再由當前控制器選擇進行何種方式的界面推出。在OC中能夠直接經過類名轉化爲class並生成控制器,但在Swift中因爲多了命名空間的緣由須要由空間名+類名的方式來生成。具體代碼以下:swift

//這裏的BQRouterCommProtocol是爲數據傳輸準備的協議,會在數據傳輸部分進行說明
static func loadVc<T: BaseVc>(vcName:String, spaceName: String? = nil) -> T where T:BQRouterCommProtocol {
        var clsName = ""
        if let space = spaceName{
            clsName = space + "." + vcName
        }else {
            let spaceName = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String
            clsName = spaceName! + "." + vcName
        }
        let cls = NSClassFromString(clsName) as? BaseVc.Type
        let vc = cls?.init()
        if let valueVc = vc {
            return valueVc as! T
        }else {
            //當沒法生成對應的控制器時,返回一個默認的錯誤控制器用以說明
            return ErrorVc() as! T
        }
    }

數據傳輸

當要推出的控制器視圖有了以後,便要考慮數據傳輸問題,首先是正向傳值,這種比較簡單直接略過,咱們須要主要思考的是反向傳值方式,爲了作到解耦,筆者最開始思考的方式是直接使用NotificationCenter。考慮到其使用時效率問題(其本質原理是經過KVO方式去進行操做),所以筆者模擬通知中心設計了一個路由通訊管理器。設計模式

通訊管理器設計思路
  1. 通訊管理器註冊進行通訊的控制器
  2. 通訊管理器傳輸數據到可接受的控制器
  3. 當控制器釋放時,從通訊管理器中反註冊

先設計通訊協議,目的是保證數據傳輸方式的統一和規範架構

protocol BQRouterCommProtocol:NSObjectProtocol {
    var removeIndex: Int { get set } //用於反註冊使用,初始數值小於0
    func loadVcInfo(params:Any) //用於正向傳值
    func reciveRouterComm(name:Notification.Name, params:Any?) //用於反向傳值
}

爲了保證註冊後控制器不被通訊管理器強引用,中間使用代理類進行橋接,以便控制器能夠正常析構,在反註冊後就移除中間代理類app

class BaseVcProxy: NSObject {
    weak var vc:BQRouterCommProtocol?
    var notifiArr:[Notification.Name] = []
    init(vc: BQRouterCommProtocol) {
        self.vc = vc
        super.init()
    }
}

最後進行通訊管理post

這裏模仿通知中心的方式來進行通訊管理
//註冊(重複註冊無效)
class public func addRouterComm(names:Notification.Name..., target: BQRouterCommProtocol) 
//發送數據
class public func postRouterComm(name:Notification.Name, params:Any? = nil)
//反註冊
class public func romveRouterComm(target: BQRouterCommProtocol)

通訊管理器關鍵代碼以下:url

private func addComm(names:[Notification.Name], target: BQRouterCommProtocol) {
    for weakVc in self.commObjcs {
        if let vc = weakVc.vc {
            if (vc as! UIViewController) == (target as! UIViewController){
                return
            }
        }
    }
    let weakVc = BaseVcProxy(vc: target)
    weakVc.notifiArr.append(contentsOf: names)
    self.commObjcs.append(weakVc)
    target.removeIndex = self.commObjcs.index(of: weakVc)!
}
private func postComm(name:Notification.Name, params:Any?) {
    for weakVc in self.commObjcs {
        if let vc = weakVc.vc {
            if weakVc.notifiArr.contains(name) {
                vc.reciveRouterComm(name: name, params: params)
            }
        }
    }
}
private func removeComm(target: BQRouterCommProtocol) {
    if target.removeIndex >= 0 {
        self.commObjcs.remove(at: target.removeIndex)
    }
}

到這裏你們應該都看出筆者路由設計的概貌了,如仍是不太清楚,建議對照demo進行梳理spa

後記

此路由機制的設計相對來講比較簡單,卻也是路由機制的主幹部分。若是想要豐富細化,仍有不少細節可處理。這個就看你們項目的實際需求了。在筆者看來路由機制其實能夠做爲一種架構設計來講,具體到控制其中又能夠分爲各類設計模式了。但願這篇文章能讓你們瞭解到Swift路由設計的方式。若有任何錯誤之處歡迎指正!

相關文章
相關標籤/搜索