不要急,不要怕

静态库的封装

  1. 静态库和动态库有什么异同?

静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。

静态库和动态库都是闭源库,只能拿来满足某个功能的使用,不会暴露内部具体的代码信息,而从github上下载的第三方库大多是开源库。

  1. 这两种库都有哪些文件格式?
    静态库:.a和.framework (windows:.lib , linux: .a)

动态库:.dylib和.framework(系统提供给我们的framework都是动态库!)(windows:.dll , linux: .so)

注意:两者都有framework的格式,但是当你创建一个framework文件时,系统默认是动态库的格式,如果想做成静态库,需要在buildSetting中将Mach-O Type选项设置为Static Library就行了!

  1. .a文件和.framework文件的区别?

.a是一个纯二进制文件,不能直接拿来使用,需要配合头文件、资源文件一起使用。

将静态库打包的时候,只能打包代码资源,图片、本地json文件和xib等资源文件无法打包进去,使用.a静态库的时候需要三个组成部分:.a文件+需要暴露的头文件+资源文件;

.framework中除了有二进制文件之外还有资源文件,可以拿来直接使用。

  1. 制作静态库需要注意的几点:

注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件+.h+其它资源文件的形式,不同的是,.a本身就是二进制文件,需要我们自己配上.h和其它文件才能使用,而.framework本身已经包含了.h和其它文件,可以直接使用。
图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。
category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linkerflags的值为-ObjC。
如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。

  1. .framework动态库的主要作用:

framework本来是苹果专属的内部提供的动态库文件格式,但是自从2014年WWDC之后,开发者也可以自定义创建framework实现动态更新(绕过apple store审核,从服务器发布更新版本)的功能,这与苹果限定的上架的app必须经过apple store的审核制度是冲突的,所以含有自定义的framework的app是无法在商店上架的,但是如果开发的是企业内部应用,就可以考虑尝试使用动态更新技术来将多个独立的app或者功能模块集成在一个app上面!(笔者开发的就是企业内部使用的app,我们将企业官网中的板块开发成4个独立的app,然后将其改造为framework文件集成在一款平台级的app当中进行使用)

目前 iOS 上的动态更新方案主要有以下 4 种:

HTML 5
lua(wax)hotpatch
react native
framework
前面三种都是通过在应用内搭建一个运行环境来实现动态更新(HTML 5 是原生支持),在用户体验、与系统交互上有一定的限制,对开发者的要求也更高(至少得熟悉 lua 或者 js)。

使用 framework 的方式来更新可以不依赖第三方库,使用原生的 OC/Swift 来开发,体验更好,开发成本也更低。

由于 Apple 不希望开发者绕过 App Store 来更新 app,因此只有对于不需要上架的应用,才能以 framework 的方式实现 app 的更新。

原文链接,这里讲的很详细

如何创建.a:

封装.a
创建后我们可以多创建几个类用于试验,
这里我建了两个类和一个Category

如何创建.a和farmWork

选择要暴漏出来的.h文件,
点加号选择要暴漏的.h
这里上文提到的“如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。”没搞出来,以后有空了再说,感觉如果只暴漏一个.h的话,要省事的多.

修改导出product配置
修改导出product配置
修改编译指令集
修改编译指令集

在虚拟机上【Command+B】运行,然后右键点击products下的.a文件,这时已经从红色变为黑色的了,show in finder,旁边点击include里的文件夹一层层点开,就是要暴漏的.h,
同样的在真机上【Command+B】运行,.a show in finder.

lipo -create 真机下.a地址 虚拟机下.a地址 -output 要放到的地址/.a 名字

这里补充一个命令lipo -info xxoo.a ,,查看当前(.a)静态文件是合并过的还是没合并过的呢,即支持哪些平台,lipo的-info参数。

SianMac:Desktop yusian$ lipo -info xxoo.a 
Architectures in the fat file: xxoo.a are: armv7 i386 x86_64 arm64

这应该是合并过的静态文件,支持armv7 i386 x86_64 arm64平台,模拟器:iPhone4s~5 : i386 iPhone5s~6plus : x86_64
真机:iPhone3gs~4s : armv7 iPhone5~5c : armv7s iPhone5s~6plus : arm64
现在腾讯sdk已经不支持了i386了,所以做了qq分享的话,虚拟机上的4s会爆红。

好了,现在.a就已经打包好了,将它和暴漏出的.h文件随便拖到一个新建的项目中,运行后你会发现报错,不要惊慌,这是因为我们的静态库里有Category方法。调用时报错“unrecognized selector send to instance.”。这个算是一个官方的已知bug,详情见苹果文档。简单点说,如果你写了一个静态库并且里面有Category,那你就需要让使用者在他们工程的编译参数”Other Linker Flags”里面添加 “-ObjC “选项。

如果报了更多的问题,戳这里

再次运行时发现了一个重没见过的错误,source file is not valid utf-8,原来是开始捣鼓时引入了#import “libWQA.a”,这个做法是不对的。。。好了,//掉后再一运行,就好了,第一个.a文件做出来了。

framework静态库的创建:

呼,太阳晒得我好舒服啊,迷了一会~~~没有项目的日子好悠闲啊~~

把farmwork也试了一次,过程和.a差不多,按他的步骤来就好了,哪天用到了再见招拆招吧!,这里注意修改生成的Mach-O格式,把Dynamic Library修改为Static Libray,把动态库改为静态库,动态库不让上线的,当然如果是企业用的话就无所谓了。

感想:

就像是🍎的系统函数一样不给看.m文件一样,只给保留了你需要的函数接口,像一个黑盒子,好像除了sdk什么的方便组件式开发。个人没有必要这么干,又重又容易出问题,除非是一些特别“有含量”的代码,而且这代码还不想让别人看到(坏笑ing).