专栏名称: 南栀倾寒
iOS工程师 有兴趣加入群173499350 此简书只做同步使用,原文在 https://www.valiantcat.cn/
目录
相关文章推荐
表舅是养基大户  ·  债市反转了吗 ·  8 小时前  
唐史主任司马迁  ·  这个组合一直是时乖命蹇。说右侧信号马上就被砸 ... ·  16 小时前  
诸海滨科新先声  ·  【开源北交所】一致魔芋:休闲食品需求放量+魔 ... ·  昨天  
姚尧  ·  3月12日股市前瞻 ·  昨天  
51好读  ›  专栏  ›  南栀倾寒

组件化-动态库实战续

南栀倾寒  · 简书  ·  · 2017-05-16 11:36

正文

原文地址 ,此简书只做备份,强烈推荐原文,毕竟格式比简书好看,还清晰

回忆之前

上篇文章中我们已经完美的解决了 使用 swift第三方库 ,使用 混编的组件 ,使用 use_framework! ,但是会带来别的问题。
果然是生命不息,折腾不止啊。

不建议在组件化的项目中使用Swift来写业务。

Q: C++/C 静态库依赖问题
A: 回想下我们在做C或者C++开发的时候。如果一个静态库依赖另外一个静态库(A依赖B)。那么被依赖库B升级的时候A用重新编译吗? 不一定,如果是一些方法的新增,维护,不一定会让A重复编译;但是如果修改了B里面的数据结构,A里面又用到了这些数据结构,那么很大可能性我们就要重新编译A了。
Q: Objective-C 静态库依赖问题
A: 回想下我们在iOS中出现上述的依赖问题,貌似也没有见到要重新编译A的情景。主要是Objc2.0引入了 non-fragile特性,同时OC是严重依赖于Runtime的,只要接口兼容,就算你修改了B中的数据结构,一般也是不需要重新编译A的。如果你不明白non-fragile 请看文后的参考链接
Q: Swift中库依赖问题
A: 由于Swift不和OC一样,所有的OC方法都是通过Runtime动态调度的。Swift对于方法是存在静态调度和动态调度2种的。所以Swift的库依赖极易引起 二进制兼容性问题 。更多关于Swift库二进制接口(ABI)兼容性问题,请参考文后链接。

Q: 为什么不建议在组件化的项目中使用Swift或者和OC混编来写业务?
A: 首先在组件化初期的时候,我们能做到的一般是基础库抽离,业务组件分离这些。但是一般来说我们这时候的壳工程,接入这些分离的组件的时候都是使用源码接入,这时候问题暂时显现不出来。
第二步。当我们的组件化的脚步越走越远的时候,我们出于多方面的考虑可能有以下需求。

  1. 开发时重复编译是痛点。我们可能更希望提供的是二进制版本,节省下大量的编译耗时;
  2. 我们可能要做权限管理。有时候一个公司业务和人员规模都非常庞大。我们基础库设计到跨业务,跨APP使用。我们希望不同团队有不同基础组件的读写权限。那么我们更可能偏向提供二进制库加文档的形式。

综上: 由于使用Swift开发ABI不兼容问题更易出现。在组件化的项目中,不建议使用Swift或者混编。

动态库过多问题

上面说到的问题(麻烦)其实是带给开发者的麻烦,但是动态库多了会给用户带来麻烦(APP启动耗时)。用了混编的项目我们在 Podfile 里面势必要写 use_framework! ,上篇文章中我们也说到用了这个指令。 CocoaPods 会帮我们把所有的库全部编译为动态库。这些动态库是在APP启动时做去加载的。我们在组件化的时候,自己的业务组件马上接近上百个。可以预想到以后随着组件化的越来越深入,这些库会越来越多。这个时间可能会达到1s的量级。对于用户 这是不可接受的。关于动态库过多导致的启动慢的问题请参考文后的参考链接。

结合公司目前的情况的解决方案

我们公司目前的情况: Swift第三方库个别,混编组件个别。既然都是个别的,我们总不能因为这些个别的特殊case让APP原本的1个二进制文件变成 1个二进制文件+上百个动态库framework。这肯定是不合理的。
解决办法

  1. 不使用Swift,包括第三方库和混编组件
  2. 部分组件(含有Swift)动态库化,其他部分仍旧整合进app的二进制中
    首先来看办法1直观感觉是不合适。首先很多公司的项目在做组件化的时候项目已经达到一定程度(没有一定规模也没必要做组件化),这就意味着大部分APP是有历史包袱的。首先重写这些已有的组件或者功能肯定是有风险的,在公司业务多。用户量大的情况下,影响面会更大,虽然这样是一劳永逸的,但是同时风险是更大的。我们在做组件化的工作中,改善大家开发的痛点,提高开发效率才是主要目标。至于重构甚至重写则是业务方的重心。
    第二种办法就是做到部分组件动态库化。
    我们来回忆下静态库的特点。静态库和主工程链接的时候会把库里面的代码复制到可执行文件中。对于这部分符号在APP启动时会省去load,rebase ,binding的时间。那么在iOS平台中嵌入式动态库的特点是不把库里面的代码复制到可执行文件中,而是单独复制到APP里面的frameworks路径下。所以通常来说动态库节省内存。在iOS平台上做不到。静态库的缺点是会让APP安装包增大。那么我们自己做的嵌入式动态库也会有这个问题。并且还会导致APP启动变慢。那岂不是优点变成了缺点~~.
    以上讨论只在正常项目且上架到APP Store渠道,越狱开发和企业版证书发布不做讨论

组件化部分动态库实战

上篇文章中我们知道 只要你的组件库中使用到了Swift。以 源码 的方式提供给壳工程使用的时候一定要加上 use_framework! , 那么就变成前文说到了上百个动态库了。 那么我们如果不以源码的形式引入呢。对于这些含有Swift的下层组件是无依赖的。我们直接将其编译为动态库提供二进制。那么我们在主工程使用的时候就不需要加入 use_framework! .

#use_frameworks!

source 'https://github.com/ValiantCat/LJWXSDK'
source 'https://github.com/CocoaPods/Specs.git'  #官方仓库的地址



target 'LJA_Example' do
  pod 'LJA', :path => '../'
  pod 'LJB', :path => '../'

    pod 'LJCharts'
end

那么我们拉下来的项目结构是这样的







请到「今天看啥」查看全文