欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS?Lotusoot模塊化工具應(yīng)用的動(dòng)態(tài)思路

 更新時(shí)間:2022年08月01日 17:07:50   作者:dengjiangszhan  
項(xiàng)目的不斷更迭,導(dǎo)致項(xiàng)目越來越大,越來越臃腫,為了讓項(xiàng)目更加條理,需要對項(xiàng)目進(jìn)行模塊化處理,為了減少模塊之間的耦合,于是就有了Lotusoot這個(gè)工具

下文,寫的是 Swift 依賴

OC 庫,沒有命名空間

組件化的要點(diǎn)-約定

個(gè)人覺得

例如,URL 路由的注冊,就是把約定的信息,傳過去。作為服務(wù)。

Lotusoot 包含服務(wù)調(diào)用,短鏈的注冊與調(diào)用

下面著重講服務(wù)調(diào)用,短鏈略

場景

project 有兩個(gè)依賴 A (協(xié)議) 和 B (協(xié)議的實(shí)現(xiàn)者,提供服務(wù))

project 引用 A,知道了協(xié)議信息

project 不引用 B , project 對 B 一無所知

這樣 project 把 B 去掉,編譯的更快

B 依賴 A, 引用 A, 實(shí)現(xiàn) A 的協(xié)議,提供服務(wù)

調(diào)用服務(wù)

        // 拿到 key
        let lotus = s(AccountLotus.self)
        // kv 取得提供服務(wù)的實(shí)例
        let accountModule: AccountLotus = LotusootCoordinator.lotusoot(lotus: lotus) as! AccountLotus
        // 調(diào)用服務(wù)
        accountModule.login(username: "zhoulingyu", password: "wow") { (error) in
            print(error ?? "1234")
        }

第 3 步,調(diào)用服務(wù)很簡單

第 2 步,挺精彩,充分使用了 Swift 編譯時(shí)的靜態(tài)特性

協(xié)議的方法,編譯時(shí)確定了

需要幾個(gè)參數(shù),啥類型的,一般都可以顯式使用

不用看到一個(gè)參數(shù)字典,啊,這是啥

// 第 2 步。從下面取
// 鍵值對,值是提供服務(wù)的對象
var lotusootMap: Dictionary = Dictionary<String, Any>()

第 1 步, 拿到鍵

這里把協(xié)議名,作為 key

// 使用泛型,取其描述
// 協(xié)議,轉(zhuǎn)協(xié)議名
public extension String {
    init<Subject>(_ instance: Subject) {
        self.init(describing: instance)
    }
}
/// 通過 Subject 快速獲取字符串
public func s<Subject>(_ instance: Subject) -> String {
    return String(instance)
}

注冊服務(wù)

1, Project 沒有 import B ( 提供服務(wù) ), 怎么使用 B 的功能?

public static func registerAll(serviceMap: Dictionary<String, String>) {
        for (lotus, lotusootName) in serviceMap {
            // lotus, 協(xié)議名
            // lotusootName, 包名.類名
            let classStringName = lotusootName
            // 反射,產(chǎn)生類
            // 提供服務(wù)的類,一定是 NSObject 的子類,擁有 init 方法 ( 這是個(gè)約定 )
            let classType = NSClassFromString(classStringName) as? NSObject.Type
            if let type = classType {
                // 產(chǎn)生對應(yīng)的實(shí)例,強(qiáng)轉(zhuǎn)為遵守協(xié)議的 ,即可
                let lotusoot = type.init()
                register(lotusoot: lotusoot, lotusName: lotus)
            }
        }
    }

2, 這里使用 python 腳本注冊,編譯的時(shí)候拿到信息 協(xié)議名:包名.類名

通過約定, 標(biāo)記

// @NameSpace(ZLYAccountModule)
// @Lotusoot(AccountLotusoot)
// @Lotus(AccountLotus)
class AccountLotusoot: NSObject, AccountLotus {}

python 腳本找出標(biāo)記,整合,放入 plist 文件中

1, 腳本入口

lotusootSuffix = 'Lotusoot'
length = len(sys.argv)
if length != 3 and length != 4:
    print 'parameter error'
    os._exit(1)
if length == 4:
    lotusootSuffix = sys.argv[3]
    lotusootFiles = findLotusoots(scanPath, lotusootSuffix + '.swift')
else:
    // 走這里
    lotusootFiles = findAmbiguityLotusoots(scanPath)

翻閱每一個(gè) swift 文件

def findAmbiguityLotusoots(path):
    list = []
    for root, subFolders, files in os.walk(path):
        # Ignore 'Target Support Files' and 'Pods.xcodeproj'
         // 不需要處理的,不處理
        if 'Target Support Files' in subFolders:
            subFolders.remove('Target Support Files')
        // 不需要處理的,略
        if 'Pods.xcodeproj' in subFolders:
            subFolders.remove('Pods.xcodeproj')
        // 每一個(gè)文件
        for f in files:
             // 每一個(gè) Swift 文件
            if f.endswith('.swift'):
                // 獲取標(biāo)記的配置
                tup = getLotusootConfig(os.path.join(root, f))
                if tup[0] and tup[1] and tup[2]:
                    // 三者都滿足,把文件路徑,給添加了
                    list.append(f)
    return list

掃描每一行,

獲取配置,上面看到的包名,命名空間

@NameSpace(ZLYAccountModule)

上面看到的類名

@Lotusoot(AccountLotusoot)

上面看到的 key ( 協(xié)議名 )

@Lotus(AccountLotus)

def getLotusootConfig(file):
    lotus = ''
    lotusoot = ''
    namespace = ''
    // 翻閱,文件的每一行
    for line in open(file):
        // 上面看到的 key
        if getLotus(line):
            lotus = getLotus(line)
         // 上面看到的類名
        if getLotusoot(line):
            lotusoot = getLotusoot(line)
        // 上面看到的包名,命名空間
        if getNameSpace(line):
            namespace = getNameSpace(line)
    return (lotus, lotusoot, namespace)

… 還有好多,

邏輯是獲取配置,寫入一個(gè) plist

運(yùn)行的時(shí)候,啟動(dòng)

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        LotusootCoordinator.registerAll()
        return true
    }

注冊就是,讀取剛才寫入的 plist, 作為 [協(xié)議名 : 包名.類名 ] 的字典,

@objc public static func registerAll() {
        let lotusPlistPath = Bundle.main.path(forResource: "Lotusoot", ofType: "plist")
        if let lotusPlistPath = lotusPlistPath {
            let map = NSDictionary(contentsOfFile: lotusPlistPath)
            registerAll(serviceMap:  map as! Dictionary<String, String>)
        }
    }

與上文,相呼應(yīng)

動(dòng)態(tài)思路

進(jìn)入動(dòng)態(tài)思路, 動(dòng)態(tài)地注冊 KV ( 協(xié)議名: 服務(wù)庫名.類名)

上文有一個(gè)印象,知道場景,即可

寫文,當(dāng)寫長,

怎樣體現(xiàn)我,10 年工作經(jīng)驗(yàn)?

上文沒有,堅(jiān)持湊字?jǐn)?shù)

1,project 拿到 key (協(xié)議名) ,可以的

2,project 拿到所有的依賴信息

通過 MachO 可以

3,project 拿到服務(wù)類的名稱

確保 module B 的類名 = key ( 協(xié)議 ) + Cls

MachO 拿到所有依賴庫的名稱, 每一個(gè) + “.” + key ( 協(xié)議 ) + Cls= MachO 拿到所有依賴庫的名稱, 每一個(gè) + “.” + module B 的類名

然后,看能不能實(shí)例化,

能夠?qū)嵗?,?OK

試了一圈,不能夠?qū)嵗?,就?bào)錯(cuò)

可能依賴 B, 沒有添加

可能依賴 B 的類名,寫錯(cuò)了

project 拿到服務(wù)類的名稱, 優(yōu)雅的

確保 module B 的類名 = key ( 協(xié)議 ) + Cls,

硬編碼,是不好的

依賴 A ( 放協(xié)議的 ), 添加一個(gè)協(xié)議

public protocol Maid{
    var name: String{ get }
}

module B 里面,必須有一個(gè)叫 key (協(xié)議) + C 的類

該類,遵守 Maid 協(xié)議。

通過協(xié)議屬性,返回 B 中服務(wù)類的名稱

class AccountLotusC: NSObject, Maid{
    var name: String{
        return String(reflecting: AccountLotusoot.self)
    }
}

這個(gè)過程,與上文模塊化利用協(xié)議的設(shè)計(jì),比較一致

約定是,實(shí)現(xiàn)協(xié)議的服務(wù)模塊,

一定有一個(gè) key + C 的類

提供服務(wù)類的名稱

硬編碼,比較輕微

代碼實(shí)現(xiàn)

1、MachO 獲取命名空間

import MachO
lazy var moduleNames: [String] = { () -> [String] in
        // 找到 project 名稱,一會去除
        let mainNameTmp = NSStringFromClass(LotusootCoordinator.self)
        guard let mainName = mainNameTmp.components(separatedBy: ".").first else{
            fatalError("emptyMainProject")
        }
        var result = [String]()
        let cnt = _dyld_image_count()
        // 處理所有的包,系統(tǒng)的,用戶的
         for i in 0..<cnt{
             if let tmp = _dyld_get_image_name(i){
                 let name = String(validatingUTF8: tmp)
                 // 系統(tǒng)的,不用管
                 if let candidate = name, candidate.hasPrefix("/Users"){
                     if let tmp = candidate.components(separatedBy: "/").last{
                         // 去除 project 的
                         if tmp != mainName{
                             // 拿到用戶依賴
                             result.append(tmp)
                         }
                     }
                 }
             }
         }
         return result
    }()

以上,模擬器 OK, 真機(jī)沒試過 ( 手頭沒開發(fā)證書 )

2、包名+類名的驗(yàn)證

@objc public static func lotusoot(lotus: String) -> Any? {
        // 已經(jīng)緩存了
        if let val = sharedInstance.lotusootMap[lotus]{
            return val
        }
        else{
            var i = 0
            let names = LotusootCoordinator.sharedInstance.moduleNames
            let cnt = names.count
            // 遍歷,用戶包
            while i < cnt{
                // 按照約定,嘗試制造助手類
                let classType = NSClassFromString(names[i] + "." + lotus + "C") as? NSObject.Type
                if let type = classType {
                    // 實(shí)例化,助手類
                    let assist = type.init()
                    if let maid = assist as? Maid{
                         // 拿到 module B 的服務(wù)類的名稱
                        let classType = NSClassFromString(maid.name) as? NSObject.Type
                        if let type = classType {
                            // 將 module B 的服務(wù)類,實(shí)例化
                            let lotusoot = type.init()
                            register(lotusoot: lotusoot, lotusName: lotus)
                        }
                        // 默認(rèn)是,一個(gè) module 一個(gè)服務(wù)類,
                        // 排除掉,使用過的用戶類
                        LotusootCoordinator.sharedInstance.moduleNames.remove(at: i)
                        break
                    }
                }
                i+=1
            }
            if let val = sharedInstance.lotusootMap[lotus]{
                return val
            }
            else{
                fatalError("name Module of" + lotus)
            }
        }
    }

GitHub repo

到此這篇關(guān)于iOS Lotusoot模塊化工具應(yīng)用的動(dòng)態(tài)思路的文章就介紹到這了,更多相關(guān)iOS Lotusoot模塊化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • iOS簡單登錄LoginViewController、注冊RegisterViewController等功能實(shí)現(xiàn)方法

    iOS簡單登錄LoginViewController、注冊RegisterViewController等功能實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了iOS簡單登錄LoginViewController、注冊RegisterViewController、UcenterViewController功能實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • iOS開發(fā)實(shí)現(xiàn)簡單抽屜效果

    iOS開發(fā)實(shí)現(xiàn)簡單抽屜效果

    這篇文章主要為大家詳細(xì)介紹了iOS開發(fā)實(shí)現(xiàn)簡單抽屜效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 以代碼實(shí)例總結(jié)iOS應(yīng)用開發(fā)中數(shù)據(jù)的存儲方式

    以代碼實(shí)例總結(jié)iOS應(yīng)用開發(fā)中數(shù)據(jù)的存儲方式

    這篇文章主要介紹了iOS應(yīng)用開發(fā)中數(shù)據(jù)的存儲方式的實(shí)例總結(jié),代碼為傳統(tǒng)的Objective-C語言,需要的朋友可以參考下
    2016-02-02
  • 總結(jié)IOS界面間跳轉(zhuǎn)的幾種方法

    總結(jié)IOS界面間跳轉(zhuǎn)的幾種方法

    前段時(shí)間被問到界面間的跳轉(zhuǎn)有幾種方式?想不到說的竟有點(diǎn)含糊其辭,于是就想總結(jié)一下。有句話說的好,“前人種樹,后人乘涼”,目前作為一個(gè)乘涼者,我也希望能種一些樹木,為代碼世界營造一份清新。好了,話不多說,進(jìn)入主題。
    2016-08-08
  • iOS獲取手機(jī)ip地址代碼

    iOS獲取手機(jī)ip地址代碼

    這篇文章主要為大家詳細(xì)介紹了iOS獲取手機(jī)終端ip地址的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • iOS WebSocket長鏈接的實(shí)現(xiàn)方法

    iOS WebSocket長鏈接的實(shí)現(xiàn)方法

    WebSocket是HTML5一種新的協(xié)議,它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,本篇文章介紹了iOS WebSocket長鏈接的使用,有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • iOS 修改alertViewController彈框的字體顏色及字體的方法

    iOS 修改alertViewController彈框的字體顏色及字體的方法

    下面小編就為大家分享一篇iOS 修改alertViewController彈框的字體顏色及字體的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • iOS APP中保存圖片到相冊時(shí)崩潰的解決方法

    iOS APP中保存圖片到相冊時(shí)崩潰的解決方法

    下面小編就為大家分享一篇iOS APP中保存圖片到相冊時(shí)崩潰的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • IOS開發(fā)Swift?與?OC相互調(diào)用詳解

    IOS開發(fā)Swift?與?OC相互調(diào)用詳解

    這篇文章主要為大家介紹了IOS開發(fā)Swift?與?OC相互調(diào)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • iOS底層探索之自動(dòng)釋放池原理解析

    iOS底層探索之自動(dòng)釋放池原理解析

    這篇文章主要介紹了iOS底層探索之自動(dòng)釋放池,自動(dòng)釋放池的壓棧和出棧,通過結(jié)構(gòu)體的構(gòu)造函數(shù)和析構(gòu)函數(shù)觸發(fā),自動(dòng)釋放池的本質(zhì)是__AtAutoreleasePool結(jié)構(gòu)體,包含構(gòu)造函數(shù)和析構(gòu)函數(shù),本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-06-06

最新評論