惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
L
LangChain Blog
Y
Y Combinator Blog
Microsoft Security Blog
Microsoft Security Blog
宝玉的分享
宝玉的分享
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
D
Docker
B
Blog
Engineering at Meta
Engineering at Meta
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
G
Google Developers Blog
博客园 - Franky
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
U
Unit 42

博客园 - 裸奔的小鸟

Screen Pen FAQ StoreAssets FAQ Heart Beat FAQ Learn Chinese FAQ 天天记单词 FAQ Swift 面向协议编程的一点见解 Swift 项目中添加main方法 Swift 简单工厂模式、工厂方法模式、抽象工厂模式解析 ScriptToApp FAQ Eye Protection FAQ Live Score FAQ Quick Search FAQ iPhone Screen FAQ Quick Launcher FAQ Zoom Me FAQ Show Desktop Pro FAQ The Startup Manager FAQ Finder Quick Menu FAQ The App Locker FAQ 【转载】在block中使用weakSelf/strongSelf
Swift 模块化框架的实现以及模块之间的解藕
裸奔的小鸟 · 2020-04-01 · via 博客园 - 裸奔的小鸟

一般比较大的项目都会使用到模块化的方式来管理各个组件, 这样每个模块的owner只需要专注于该模块的开发,而不需要关心其他模块. 于是本文简单介绍一下Swift模块化框架的简单实现.

模块化实现

整体思路是这样的,  app启动后先初始化一个模块管理类ModuleManager, 然后由ModuleManager去初始化各个模块. 可以参考下面的结构图

App 启动之后调用ModuleManager的 applicationDidFinishLaunching等方法, 然后ModuleManager 负责调用每个模块的applicationDidFinishLaunching等方法.

不分实现的代码如下:

  • 先定义所有模块都必须遵循的协议 ModuleProtocol , ModuleProtocol是继承自UIApplicationDelegate
  • 然后根据模块的名字注册该模块,比如这个地方是注册"ModuleA.ModuleClassA" (注意swift里是根据 "#模块名.#类名" 的形式来找到该类)
  • 然后在 applicationDidFinishLaunching 方法中遍历, 从而调用所有已注册模块的applicationDidFinishLaunching方法
@objc public protocol ModuleProtocol:UIApplicationDelegate {
   static func create() -> ModuleProtocol?
}
func registerModule(_ moduleName:String){
    guard let moduleClass:AnyClass = NSClassFromString(moduleName) else{return}
    var moduleContext:ModuleContext = ModuleContext()
    moduleContext.moduleClass = moduleClass
    moduleContext.moduleName = NSStringFromClass(moduleClass)
    guard let moduleObject:ModuleProtocol = (moduleContext.moduleClass as! ModuleProtocol.Type).create() else {
        return
    }
    moduleContext.modueleObject = moduleObject
    moduleContextArray.append(moduleContext)
}
public func applicationDidFinishLaunching(_ application: UIApplication) {
    for context in moduleContextArray {
        if (context.modueleObject?.responds(to: #selector(applicationDidFinishLaunching(_:))))!{
            context.modueleObject?.applicationDidFinishLaunching?(application)
        }
    }
}

模块之间的解藕

开发过程中经常会遇到这样的情况, 模块A 需要调用 模块B的方法, 模块B 需要调用 模块C 的方法, 而模块C 又调用了 模块A 的方法. 从而导致循环依赖.

为了解决这样的问题, 就需要对各个模块进行解藕. 具体思路是这样的: 对于每一个需要被外部调用的模块(比如ModuleA), 我们会抽离出来一个独立的service模块 ModuleAService 以供给外部模块的调用. 这样ModuleB 只需要依赖 ModuleAService 而不需要依赖 ModuleA, 从而完成解藕

下面是部分实现代码:

  • 首先定义一个所有Service模块都必须遵循的协议ServiceProtocol
  • 然后注册所有的Service模块, 比如"ModuleAService.ModuleAService"
  • 在ModuleB中就可以获取 ModuleAService 协议的实例, 并调用该协议的方法 majorFunctionInModuleA. 由于ModuleA是遵循ModuleAService协议的, 并且已经实现了协议方法majorFunctionInModuleA,所以最终达到了在ModuleB中不引入ModuleA就调用ModuleA的方法的目的.
@objc public protocol ServiceProtocol{
    
}
func registerService(_ serviceName:String){
    guard let serviceClass:AnyClass = NSClassFromString(serviceName) else{
        return
    }
    var count:UInt32 = 0
    guard let protocolList = class_copyProtocolList(serviceClass, &count) else{
        return
    }
    var serviceProtocolList:[Protocol] = []
    for i in 0..<count {
        let foundServiceProtocols = findServiceProtocols(protocolList[Int(i)])
        serviceProtocolList.append(contentsOf: foundServiceProtocols)
    }
    
    for serviceProtocol in serviceProtocolList {
        setServiceClass(serviceClass, forProtocol: serviceProtocol)
    }
}
let instanceList:[ModuleAService] = ModuleManager.sharedInstance.servicesForProtocol(ModuleAService.self) as! [ModuleAService]
let instance:ModuleAService = instanceList.first!
instance.majorFunctionInModuleA()
public class ModuleAServiceClass: NSObject,ModuleAService  {
    
    public func majorFunctionInModuleA() {
        let moduleA = ModuleClassA()
        moduleA.majorFunctionInModuleA()
    }
    
}

完整的代码请参考: https://github.com/jimwan/Swift-modularization