面试将来跳槽用iOS面试&笔试

OC底层面试题-组件化通信(下)

2021-04-22  本文已影响0人  iOS鑫

上篇我们知道了如何创建组件化项目,这篇我们来聊聊组件化的重点:组件化通信


组件化通信方法

目前所了解的主流方式有一下三种:

协议试编程

编译层面使用协议定义规范实现在不同地方,从而达到分布管理维护组件的目的。这种方式也遵循了依赖反转原则,是一种很好的面向对象编程的实践。

但是方案也很明显:

中间者

它采用中间者统一管理的方式,来控制App的整个生命周期中组件间的调用关系。同时iOS对于组件接口的设计也需要保持一致性,方便中间者统一调用

拆分的组件都会依赖中间者,但是组间之间不存在相互依赖的关系了。由于其他组件都会依赖于这个中间者相互间的通信都会通过中间者统一调度,所以组件间的通信也就更容易管理了。在中间者上也能够轻松添加新的设计模式,从而使得架构更容易扩展

好的架构一定是健壮的、灵活的中间者架构易管控带来的架构更稳固易扩展带来的灵活性

URL路由

这也是很多iOS项目使用的通信方案,它就是基于路由匹配,或者根据命名约定,用runtime方法进行动态调用URL路由思路采用了中间者模式

URL路由的优缺点

【优点】

【缺点】

URL路由方式主要是以蘑菇街为代表的MGJRouter

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:130 595 548,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

MGJRouter

其实现思路是:

MGJRouter采用URL路由,但是他的解耦能力还是有限

除了上面的MGJRouter,还有以下三方框架

target-action

这个方案是基于OC的runtime、category特性动态获取模块,例如通过NSClassFromString获取类并创建实例通过performSelector+NSInvocation动态调用方法

这种方式主要是以casatwy的CTMediator为代表

CTMediator

CTMediator其实现思路:

具体使用用法: 模块间的引用关系如下:

【优点】

【缺点】:

CTMediator源码分析

CTMediator使用URL路由处理

这个方法主要是针对远程APP的互相调起,通过openURL实现APP之间的跳转,通过URL进行数据传递

CTMediator使用的是运行时解耦,解耦核心方法如下所示:

下面主要看下有action的情况

protocol class

protocol匹配的实现思路是:

protocol比较典型的三方框架就是阿里的BeeHiveBeeHive借鉴了Spring Service、Apache DSO的架构理念,采用AOP+扩展App生命周期API形式,将业务功能基础功能模块方式以解决大型应用中的复杂问题,并让模块之间以Service形式调用,将复杂问题切分,以AOP方式模块化服务

BeeHive核心思想

【优点】

【缺点】

除了BeeHive还有Swinject

BeeHive中的Module注册

BeeHive主要是通过BHModuleManager来管理各个模块的。BHModuleManager中只会管理已经被注册过的模块

BeeHive提供了三种不同的调用形式,静态plist动态注册annotationModuleService之间没有关联每个业务模块可以单独实现Module或者Service的功能

Annotation方式注册

这种方式主要是通过BeeHiveMod宏进行Annotation标记

这里针对__attribute需要说明一下几点

此时Module已经被存储Mach-O文件的特殊段中,那么如何取呢?

读取本地Pilst文件

load方法注册

该方法注册Module就是在load方法里面注册Module的类

其底层还是同第一种方式一样,最终会走到addModuleFromObject:shouldTriggerInitEvent:方法中

BH_EXPORT_MODULE宏里面可以传入一个参数,代表是否异步加载Module模块,如果是YES就是异步加载,如果是NO就是同步加载。

BeeHive模块事件

BeeHive会给每个模块提供生命周期事件,用于与BeeHive宿主环境进行必要信息交互感知模块生命周期的变化

BeeHive各个模块会收到一些事件。在BHModuleManager中,所有的事件定义成BHModuleEventType枚举。如下所示,其中有2个事件很特殊,一个是BHMInitEvent,一个是BHMTearDownEvent

image

主要分三种

通常做法是AppDelegate改为继承自BHAppDelegate

image

以上所有的事件都可以通过调用BHModuleManager的triggerEvent:来处理。

从上面的代码中可以发现,除去BHMInitEvent初始化事件BHMTearDownEvent拆除Module事件这两个特殊事件以外,其它所有的事件都是调用的handleModuleEvent:方法,其内部实现主要是遍历BHModules实例数组,调用performSelector:withObject:方法实现对应的方法调用

注意:这里所有的Module必须是遵循BHModuleProtocol的,否则无法接收到这些事件的消息

BeeHive模块调用

在BeeHive中是通过BHServiceManager来管理各个Protocol的。BHServiceManager中只会管理已经被注册过的Protocol。

注册Protocol的方式一共有三种,和和上面讲的注册Module是一样一一对应

Annotation方式注册

读取本地plist文件

protocol注册

主要是调用BeeHive里面的createService:完成protocol的注册

createService会先检查Protocol协议是否是注册过的。然后接着取出字典里面对应的Class,如果实现了shareInstance方法,那么就创建一个单例对象,如果没有,那么就创建一个实例对象。如果还实现了singleton,就能进一步的把implInstanceserviceStr对应的加到BHContextservicesByName字典里面缓存起来。这样就可以随着上下文传递了

Module & Protocol

这里总结一下:

辅助类

最后

几个月下来熬夜写了不少关于OC底层的文章,这个过程中对OC又有了新的认知,OC的内容研究目前告于段落!后面会分享一些自己在实际开发中的觉得比较好的封装和架构思路。我将继续探究Swift底层,也会继续更新文章,希望大家能够相互交流,一起进步。谢谢!

上一篇下一篇

猜你喜欢

热点阅读