系统的.framework是系统SDK库,有Foundation.framework、UIKit.framework、MapKit.framework等。由于苹果不开源,每个框架只提供了接口(.h文件),所有实现(.m文件或.c/.cpp文件)编译在一个.framework二进制文件中。
苹果把所有系统的.framework二进制文件统一打包到一个共享缓存文件中(dyld shared cache),共享缓存文件存储在手机路径(需要越狱才能找到):/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX。X代表ARM处理器指令集架构。
动态链接器(dyld)存储在手机路径:/usr/lib/dyld,用于在APP运行时,链接APP和系统的.framework。
两种.framework区别 静态库的形式包含.a和.framework两种形式,动态库的形式包含.dylib和系统的.framework两种形式。动态库的.framework是系统SDK才有的库,而我们自己创建出来的.framework都是静态库 静态库中.a与.framework的区别 .a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
.a文件不能直接使用,需要.h文件配合。
.framework文件可以直接使用,因为本身包含了.h文件和资源文件。
.framework = .a + .h + sorrceFile(资源文件) 静态库的优点 实现程序的模块化,将固定的业务模块化成静态库。方便共享代码,即可以和别人分享你的代码库,但别人又看不到你代码的实现。开发第三方sdk的需要,例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成静态库,别人只能调用接口,而不能知道其中实现的细节。 编译链接 源代码转成目标文件的过程:
源代码先经过预处理器进行宏替换、删除注释等工作,得到.i文件,然后编译器对.i文件进行编译,编译成汇编语言程序(扩展名.s或.asm),之后再将汇编语言程序编译成机器指令(0和1组成),得到目标文件(扩展名.o)。编译器和链接器处理流程:
源代码(.c或.cpp)→编译器→目标文件(.object)→链接器(+静态库)→可执行文件(.exe或Mach-O)链接器作用:
对于静态库,在编译链接时把多个目标文件和所用到的库文件链接在一起形成一个完整的可执行文件,可执行文件会比较大,但程序运行时就不需要库了。
对于动态库,在编译链接时把多个目标文件链接成可执行文件,但不会把库文件加入到该可执行文件中,而是在程序运行时链接库文件。 静态库制作 制作.a静态库 .a文件是一种静态库,a是archive(归档)的缩写,它是由多个.o文件归档而成新建工程,iOS --> Framework & Library --> Cocoa Touch Static Library 这里注意由于创建的是Static Library,Build Settings搜索linking,Mach-O Type默认为Static Library。 - 删除不需要的类,如StaticLibraryTool类,创建我们所需的类,如下: - 添加需要公开的头文件 - 设置静态库需要支持的最低系统版本 - 修改配置 Active Architecture Only修改为NO,否则生成的静态库就只支持当前选择设备的架构。 - 接下来可以开始编译生成.a文件了。 设备选择Generic iOS Device,即通用型真机,然后command+B编译,在工程Products目录下生成.a文件,右键Show in Finder找到.a文件所在路径,图示Products目录下的libStaticLibraryTool.a从红色(红色表示文件不存在)变成了黑色(黑色表示文件存在),此时表示提供真机使用的静态库编译成功。 接着设备切换选择任一模拟器,command+B编译,此时提供模拟器使用的静态库编译成功,如下: 这两个.a文件要么只支持真机,要么只支持模拟器,如果想真机和模拟器都能使用该静态库,需要将二者合成为一个静态库,可用终端命令实现: ```objc lipo -create 第一个.a文件路径 第二个.a文件路径 -output 最终的.a文件路径 ```
合成为一个静态库后,我们可查看合成后的静态库支持的架构,用命令:lipo -info xxx.a
,看真机和模拟器架构是否都支持。结果如下:
模拟器架构
iPhone4s ~ 5/5c : i386
iPhone5s以后机型 : x86_64
真机架构
3GS~4s : armv7
5/5c : armv7s(armv7兼容armv7s)
5s ~ iPhoneX : arm64
iPhone XS以后机型 : arm64e
如何使用.a静态库?把.a文件和公开的头文件放入一个文件夹,命名为libStaticLibraryTool。将libStaticLibraryTool文件夹添加到需要使用的工程中,如下:
libStaticLibraryTool.a添加到工程后,
Build Pases->Link Binary With Libraries 和 General->Frameworks, Libraries, and Embedded Content都会自动引入libStaticLibraryTool.a。
Build Settings->Library Search Paths也会自动设置.a文件路径,如:$(PROJECT_DIR)/DemoA/libStaticLibraryTool。
由于静态库中使用了OC的分类(Category),OC链接器只会为类建立符号表,不会为分类建立符号表,导致函数调用时(运行时)找不到分类的符号表,无法获取函数地址,函数调用失败。
解决办法:设置Other Linker Flags的值为-ObjC,为分类建立符号表。
注意:如果不做该设置,项目中引用该库,访问该库的Category接口时会崩溃
👉🏻项目地址:iOS-StaticLibrary
如果文章和项目对你有帮助,还请给个Star⭐️,你的Star⭐️是我持续输出的动力,谢谢啦😘
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)