内容简介:其实对于写文章这个事,我的内心是拒绝的,概括一下心路历程就是虽然嘴上说着不要不要,但是身体却很诚实,其实内心拒绝的原因是不知如何让枯燥的技术文儿看起来能更具吸引力,于是决定想一个极其正(you)经(huo)的标题,作为一个既不是八卦也不是爆料的技术软文来讲,给“娃”起名这个事就是迈出的艰难一步,所以标题就成了上面那样婶儿的了…背景
前言
其实对于写文章这个事,我的内心是拒绝的,概括一下心路历程就是虽然嘴上说着不要不要,但是身体却很诚实,其实内心拒绝的原因是不知如何让枯燥的技术文儿看起来能更具吸引力,于是决定想一个极其正(you)经(huo)的标题,作为一个既不是八卦也不是爆料的技术软文来讲,给“娃”起名这个事就是迈出的艰难一步,所以标题就成了上面那样婶儿的了…
背景
随着同镇侧产品的稳定前行,工作的关注点也从纯业务研发转向性能优化和用户体验,而后在使用bugly对app崩溃情况进行查看时,发现线上崩溃总数的70%来自系统的UIWebView,而崩溃的主要元凶——爆内存
看来UIWebView饱受诟病的加载网页会造成内存无限增长的问题还是没有得到很好的解决,随着苹果在iOS 8之后推出了WKWebView,其相对UIWebView有着更快的加载速度, 更低的内存占用,这些突出的优点让我们看到了解决眼下问题的方法,于是这套新Hybrid框架应运而生。
正文
这里先来领略一下新Hybrid框架图,大概长这样...
新框架由三大基础部分组成,分别是Module、Bridge和HybridVC,下面先简单介绍一下各自的职责,后续会对每个基础部分进行详细的说明。
-
Module(组件):包含所有业务Module,每一个Module都必须遵从“ModuleProtocol”协议,协议主要规定了Module具备的能力、属性和注册方法
-
Bridge(桥接器):Module组件与视图控制器HybridVC之间为解耦状态,相互之间保持隔离,Bridge负责对上述两者进行桥接并维护它们之间的业务逻辑逻辑关系
-
HybridVC(视图控制器):业务H5页面的基类,承载着两套WebView视图
一、Module组件
Module是Hybrid框架中业务逻辑实现的节点,针对业务H5页面中不同iFrame请求携带的不同action行为来区分由哪个Module节点来进行接收并处理。每一个Module组件必须遵从“ModuleProtocol”协议,协议中内容如下图:
moduleActionName为指定当前Module对应action名称、responseAction为当前Module所对应的业务实现方法、协议提供的两个optional可选的属性,为别是桥接器bridge和params(action携带的参数),Module可以依据自身需要选择是否通过@synthesize方法来得到这些可选的成员变量实现业务逻辑。
最后可以看到定义的三个宏,分别是①WBT_EXPORT_MODULE、②WBT_EXTERN_HYBRID_MODULE和③WBT_HYBRID_MODULE_END
-
WBT_EXPORT_MODULE:该宏定义做了二件事,第一、将自身注册至bridge桥接器的moduleMap,第二、实现“ModuleProtocol”协议中的moduleActionName方法。宏使用方法如下图所示
-
WBT_EXTERN_HYBRID_MODULE:相比第一个宏,WBT_EXTERN_HYBRID_MODULE完成了一个更高级的分装,其直接声明并实现了一个Module的类,类中直接完成了类的声明、成员变量获取和对应协议方法的实现,使用方法如下图所示
-
WBT_HYBRID_MODULE_END:@end结束符
二、Bridge桥接器
为了解决业务耦合问题,Module组件与视图控制器HybridVC之间不可以进行交互,全部由Bridge进行桥接,桥接器主要承载着视图业务逻辑处理和业务分发的功能,桥接器类的.h头文件包含一个初始化方法和一个delegate属性,.m实现文件包含一个全局唯一WBTModuleClassMap映射字典、一个WBTRegisterModule注册方法和类私有属性moduleMap,接下来针对每个组成部分进行进一步说明。
-
初始化方法:自定义了Bridge的初始化行为
-
delegate属性:需要遵从“BridgeProtocol”协议,协议中定义了一些optional的可选方法,如下图所示
-
bridge初始化方法:可以在初始化bridge对象的同时指定delegate属性所指向的对象(通常为载体页HybridVC),UIWebView与WKWebView的视图回调逻辑也同样由bridge统一处理,通过协议方法桥接器可以将web页面加载的生命周期行为进行回调
-
RegisterModule方法:方法中定义了一个全局唯一的字典WBTModuleCla ssMap,该字典的每个KV键值对代表action的名称和aciton所对应的Module类名称,这样在应用使用期间可能出现多个Hybrid载体页的情况下,每个载体页的moduleMap私有属性只需要从WBTModuleClassMap获取一份拷贝即可,这保证了多载体页情景下数据源不会互相污染,WBT_EXPORT_MODULE宏中也是通过在+load中调用该方法完成了将自身注册到WBTModuleClassMap中的行为。
在使用私有属性moduleMap的同时,为了节约内存采用了懒加载的方式,即当我们第一次调用actionA时,如果发现在moduleMap中actionA对应的ModuleClass是一个类而非对象时,代表当前acitonA还没有使用过,这时会将该ModuleClass初始化为一个对象,并重新插入moduleMap,覆盖当前的value,这样在下次使用的过程中就不需要再进行初始化。这种方式式避免了在一开始就将所有的ModuleClass都初始化为对象造成的资源浪费情况。
当iFrame请求被webView截获后,就会交由bridge进行分发处理,bridge此时就会依据moduleMap来找到对应的组件并执行responseAction方法。
三、视图控制器
视图控制器负责承载UIWebView和WKWebView两种类型的视图,hybridVC具备三个属性,分别为bridge、hybridType和progressView。
-
视图控制器对象会强持有bridge属性,以保障在业务交互过程中bridge不会被自动回收
-
hybridType为一个页面类型字段,用于在视图控制器初始化的过程中决定当前视图控制器承载的视图view是UIWebView还是WKWebView,在UIWebView显得如此不堪的情况仍然提供支持的原因在于为了保障框架整体的正常运行,在极端情况 下可以依据协议来对控制加载的视图类型进行动态控制,以保障线上稳定运行
-
progressView为一个加载进度条控件,由于UIWebView与WKWebView在加载视图和使用过程中无法直接辨认,所以当加载的视图为WKWebView时会在视图顶部添加一个加载进度条,用以对当前的视图类型进行区分
在webView视图的配置过程中,还用到了一个小技巧,大多数开发者在添加webView视图的时候都习惯使用addSubview的方式将当前视图添加到视图控制器的view上,这样一来,webView视图的适配工作就需要由我们自己来进行管理,随着机型尺寸的变动就需要每次对webView的frame进行计算。在这里,我们直接使用赋值的方式即self.view=webView,这样view视图(也就是webView)的生命周期、frame等信息将会由视图控制器自行管理,不再需要我们进行人为干预。
四、总结
到这里Hybrid框架的部分就讲完了,目前该框架已经应用于同镇B端APP,框架上线之后崩溃率也正如我们期待的那样,整体下降70%,接下来同镇C端APP也会完成本套框架的接入,如果对文章有疑问或者指正的同学可以及时联系我
用户体验的每一次提升都是我们作为技术人的一次成长里程碑,我们坚信未来会为用户创造更加完美的用户体验,并为此不断努力着...
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入理解Java虚拟机(第2版)
周志明 / 机械工业出版社 / 2013-9-1 / 79.00元
《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)》内容简介:第1版两年内印刷近10次,4家网上书店的评论近4?000条,98%以上的评论全部为5星级的好评,是整个Java图书领域公认的经典著作和超级畅销书,繁体版在台湾也十分受欢迎。第2版在第1版的基础上做了很大的改进:根据最新的JDK 1.7对全书内容进行了全面的升级和补充;增加了大量处理各种常见JVM问题的技巧和最佳实践;增加了若干......一起来看看 《深入理解Java虚拟机(第2版)》 这本书的介绍吧!