IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> ios组件化通讯 -> 正文阅读

[移动开发]ios组件化通讯

随着项目越来越复杂,人员越来越多,开发人员势必要面临组件化的问题,关于这个问题,有机会专门讨论下,此篇文章里只做简单涉及,重点在于组件化之后的通讯问题

组件化方式

pod lib create xxxxModule

pod会自动读取rep模板创建,期间会需要做一些偏好设置,很常规的操作

偏好可以选择创建example

创建好之后,xxxModule/xxxModule目录下产生两个Assets和Class两个目录

  • Assets 放置资源

  • Class 放置你的代码

代码跟资放置好之后,进入Example 执行pod install,Example依赖Module就会自动安装了

Xcode导航视图结构里

  • Module存在于 Pods/Development Pods/xxxModule

  • xxxModule/Pod/IFLHomeModule.podspec 配置module版本,rep地址,以及三方依赖

  • Pods/Pods 主工程Example pod依赖 及 xxxModule pod s.dependency 都会安装在Pod/Pods

  • 资源文件存放于 Pods/Development Pods/xxxModule/**

  • module里资源文件的访问

    • Pods/Development Pods/xxxModule/Pod/xxxModule.podspec 配置s.resource_buneles

    • [[NSBundle bundleForClass:[self class]].resourcePath stringByAppendingPathComponent:@“/xxxModule.bundle”]

组件策略一: target - action (CTMediator)

简单整理了下CTMediator,实现机制很简单

在这里插入图片描述

应用中的业务想要访问组件,都通过CTMediator获取目标视图,提供自己需要的组件target名称,及get名,也就是两个静态的字符串,可能是宏或者全局配置变量

CTMediator 通过目标target,根据action,通过绑定的组件拿到目标视图,完成初始化,返回给调用者。action与目标组件中的视图都是静态配置好的

其实项目代码层面没有什么问题,但组件并不是一成不变的,可能会面临多次升级,这种设计不可避免的,每次组件更新,除非组件根业务结构不发生变化,否则每次target也得调整,也就是组件与target是密不可分的

组件业务如果不是很复杂,不一定需要处理成组件,一般我面临到这种情况就是业务庞杂到影响项目协作,如果编译依赖度过高,而且效率低下,我会毫不犹豫选择组件化处理

这种target-action 方式不一定是处理组件通讯,业务模块中也可以选择处理,这样能一定程度减轻自己代码的业务侵入,target相当于做了一层业务隔离,这有助于稳定自己的业务架构设计,同时对代码也起到一定规范作用

如果要进一步解决耦合依赖问题,不只业务层面,还要考虑编译层面的效率问题,target action 可能会变得越来越繁杂,分层也会变得越来越模糊,而且需要写很多费解的target设计,个人感觉不是那么的好用,所以我就果断选择BeeHive,不只解决了组件通讯问题,更是一解耦利器 关键是协议设计很明了

组件策略二: BeeHive

为了深刻了解BeeHive,还是从源码入手追踪一遍,最后再总结

通过service获取目标实例对象

在这里插入图片描述

这个流程的目的是通过service获取到类实例,代码里最直接的体现就是 源码coding层面不用再import了,这是一种最直接的解耦方式了

以上流程图中涉及两个字典查找

  • BHContext::servicesByName

  • BHServiceManager::allServicesDict

既然涉及BHContext,不妨看下BHContext,究竟BHContext是什么

跳过具体属性不看,看方法

在这里插入图片描述

BHContext主要就是 关于实例的增删查 简单了解BHcontext就是存实例 取实例,因为现在是分析源码解耦机制,细节我们暂可省略

再查看下 BHServiceManager::allServicesDict这个字典

在这里插入图片描述

可以了解 allServicesDict 是用来注册service - class 键值信息的,两种方式,一种读取文件,一种动态注册

现在可以知道了,manager负责注册类信息,context负责缓存类信息

继续溯源

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
也就是说BeeHive在初始化阶段就完成 service - class 的静态注册

同时 BeeHive初始化 也需要完成 localModules装载 + modules注册

分析staticModules装载

在这里插入图片描述

module静态加载其实 是加载plist记录的 一些module类的信息

这里两个小细节值得关注一下

在这里插入图片描述
装载的module 有优先级
在这里插入图片描述

  • 还有就是装载modules时不能重复,如果通过缓存的modules数据源处理后续注册类逻辑的话,可能就会触发注册异常了 同样 相同的module,优先级也可能冲突

  • 还有一点更重更要:

    • 既然是初始化 读取modules plist资源文件,何来重复之说呢?

    • app dyld加载类阶段,也就是静态装载 plist资源modules之前, load会在此之前执行,load里存在 registerDynamicModule 操作,此处又个印象就行,回头会就这块分析说明

    • 还有一点猜测:目前的分析阶段,我们是单个BeeHive组件,而如果多个组件呢,其他的plist

      资源文件呢,而modules注册缓存只能是一份

由此可以看出开源作者很细节,这是顶层设计的结果,在我们在设计项目架构时,作为一名开发人员,这很值得参考

静态注册modules class 信息缓存在 BHModuleaManager::BHModuleInfos

BHModuleInfos 是个 NSMutableArray<NSDictionary *>

BHModuleManager::registedAllModules - modules注册

首先要对缓存的modules排序 (两层规则)

  • level值大的排前面

  • level相同,priority值小的,优先级高, 排前面

也就是说 module注册按照分组进行,组有优先级顺序; 组内的module同样也具有优先级顺序

这里我嗅到了些许 dl类加载的气息

  1. 其次从缓存的modules里顺序取出module 字符串,获取module类,并执行初始化获取module对象

BHModuleManager::BHModules 缓存所有的module类的对象

  1. BHModuleManager::registerAllSystemEvents注册所有系统事件

至此 module类实例对象缓存完成

在这里插入图片描述

可源码线性分析流程中断了

没关系 我们全局搜就好了

modSetup modInit

在这里插入图片描述
继续搜索

在这里插入图片描述

既然BHModuleManager缓存了一个大字典,Key:枚举事件, Value: selector, 那肯定是有专门处理事件的地儿,我们接着搜

在这里插入图片描述
在这里插入图片描述

而当前appDelegate 继承 BHAppDelegate, BeeHive配置及一些初始化在前,app launch在后,这样之前的断层就续上了

继续追踪源码
在这里插入图片描述

在这里插入图片描述
我们知道了,application launch之前,所有缓存的module执行 modSetup modInit

modSetup -> BHServiceManager::registerService

每个module类其实绑定一个业务类,而modSetup就是通过 allServicesDict字典缓存业务类 
<Protocol:Class>

BeeHive监听app生命周期事件

在这里插入图片描述
在这里插入图片描述

BeeHive已经对一些基本事件做了管理,你只需要在你的Module类里 实现相应的事件回调协议方法就好了

当然自己可以扩展 module协议 及自定义事件

BeeHive总结

BeeHive可以分为

  • BeeHive核心

  • BHContext

  • Service注册

  • Module注册

  • Modules

  1. BHContext - service列表,module列表,编译参数

  2. BeeHive核心负责service module的注册,模块之间调度

  3. Modules其实是一个逻辑模块集合,各个module均通过BeeHive核心调度

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:36:33  更:2022-07-05 23:36:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 2:48:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码