美文网首页
iOS架构之路01 -- 静态库.a文件的制作与使用

iOS架构之路01 -- 静态库.a文件的制作与使用

作者: YanZi_33 | 来源:发表于2021-09-07 14:52 被阅读0次

    • 库是共享代码的一种方式;
    • 从本质上来说库是一种可执行代码的二进制格式,可以被载入到内存中执行;
    • 库可分为静态库动态库,在iOS中静态库有.aframework两种形式,动态库有.dylibframework两种形式,后来.dylib被替换成.tbd形式;

    静态库

    • 静态库在程序编译时会被拷贝到目标程序中,运行时不能再修改静态库,同一个静态库在不同程序中使用时,每个程序中都会拷贝导入一次,造成多份冗余拷贝,浪费内存空间;

    动态库

    • 动态库在程序编译时只链接不拷贝到目标程序,运行时由系统动态加载到内存,供程序调用,系统只会加载一次,多个程序可以共用,节省内存;注意动态库不会被拷贝到目标程序中,所以程序体积会小很多,系统的框架UIKit,Foundation等都属于动态库,但苹果不让使用自定义的动态库,若使用则审核无法通过,

    • 系统的.framework是动态库,我们自己建立的.framework是静态库,所以说framework既可以是静态库,又可以是动态库;

    .a与.framework之间的区别

    • .a是一个纯二进制文件,其不能直接使用,需要有.h文件配合才能使用;
    • .framework中除了二进制文件之外还有资源文件,其包括.a + .h + sourceFile = .framework, .framework是可以直接使用的;

    为什么要使用静态库?

    • 方便共享代码,便于合理使用;
    • 实现iOS程序的模块化,可以将固定的业务模块化成静态库;
    • 向别人分享你的代码库,但是不想让别人看到你代码的实现,开发第三方SDK的需要;

    iOS移动设备的CPU架构

    • 通常,我们知道电脑的CPU架构有X86和X64等,但是手机的主流CPU架构是ARM架构,因为采用ARM架构的CPU是一种微处理器,这种处理器功耗低,体积小,更适合手机使用,iPhone的CPU也是如此;
    • iOS设备常见的架构如下所示,分为模拟器与真机两大类:
    Snip20210908_49.png

    .a静态库的制作与使用

    • 本人使用的是Xcode12.4;

    • 第一步:打开Xcode,新建一个Static Library工程,如下所示:

      Snip20210906_4.png
    • 静态工程名称为MyCategory

    • 第二步:MyCategory工程创建成功后,默认会生成MyCategory.hMyCategory.m两个文件,删除MyCategory.m,保留MyCategory.h,然后在MyCategory.h文件中导入自己代码文件的所有头文件,如下所示:

      Snip20210906_6.png
    • 第三步:静态工程配置,为了能支持真机与模拟器,做以下的工程配置:

    • 针对Build Setting -> Architectures 即设置架构选项,我们来做以下详细的阐述:

      • Architectures:默认设置为arm64与armv7架构是针对真机的,说明苹果遗弃了armv7s的真机架构,如果加上armv7s需要我们手动添加
      • Build Active Architectures Only:表示编译文件是否仅仅只支持当前选中的设备所包含的架构;默认情况下Debug模式下为YES,Release模式下为NO;
      • Excluded Architectures:删除指定的架构;
    • 现做如下设置,注意我选择的Release模式,然后进行编译;

    Snip20210908_51.png
    • 真机生成的.a文件支持 arm64armv7两种架构,如下所示:
    Snip20210908_53.png
    • 然后切换到iOS模拟器,我选择的是iPhone8 Plus,再编译,生成的.a文件支持 arm64x86_64i386 三种架构,如下所示:
    Snip20210908_54.png
    • 模拟器居然也支持arm64架构,觉得有点不可思议了,从网上查相关资料说是Xcode12才会支持,这就为真机与模拟器.a文件的合并,带来隐患,下面内容有提到;

    • 关于Architectures的其他选项保持不变,手动输入真机架构,如下所示:

      Snip20210908_57.png
    • 真机生成的.a文件支持arm64,armv7 与 armv7s三种架构,如下所示:

    Snip20210908_58.png
    • 设置.a文件支持的最低系统版本 iOS Deployment Target iOS 9.0
    Snip20210908_59.png
    • 第四步:手动导入自己代码的所有.h文件,如下所示:
    Snip20210906_9.png
    • 第五步:编译前检查一下是debug模式还是release模式,我们需要选择release模式;
      分debug和release模式:
      Debug-iphoneos 文件夹里面的东西是用在真机上的
      Debug-iphonesimulator 文件夹里面的东西是用在模拟器上
      如果 Scheme 是 Release 模式,生成的文件夹就以 Release 开头;
      如下所示:
    [图片上传中...(Snip20210906_13.png-7afaae-1630915674828-0)] Snip20210906_13.png
    • 第六步:编译 Command + B,首先选择真机状态下进行编译,然后选择模拟器状态载进行编译,最后会生成libMyCategory.a静态文件,如下所示:
    Snip20210906_14.png
    • 会看到Release-iphoneosRelease-iphonesimulator两个文件夹,分别为真机与模拟器的静态库文件;

    • 第七步:静态库文件合并,即将Release-iphoneosRelease-iphonesimulator两个文件夹下的.a文件合并称一个.a,以便同时支持真机和模拟器,合并后的.a大小大约是未合并.a文件的2倍左右;

    • cd 到 Products文件夹下,执行lipo -create Release-iphoneos/libMyCategory.a Release-iphonesimulator/libMyCategory.a -output CategoryLib.a,出现报错,如下所示:

    Snip20210906_15.png
    • 其原因在于Xcode12 编译的模拟器库新增支持架构arm64,需将模拟器的arm64给排除出去即可,工程配置如下:
    Snip20210906_16.png
    • 然后在真机与模拟器状态下,重新编译,最后cd 到 Products文件夹下,执行lipo -create Release-iphoneos/libMyCategory.a Release-iphonesimulator/libMyCategory.a -output CategoryLib.a,在Products文件夹下会生成一个CategoryLib.a静态库文件,如下所示:
    Snip20210906_17.png
    • 执行file CategoryLib.a可查看其文件类型及支持的架构信息,如下所示:
    Snip20210906_18.png
    • 第八步:.a静态库的导入使用,新建一个工程Test_AProject,然后导入上面制作的.a静态库文件CategoryLib.a
      • 在桌面上新建一个文件夹MyLib,然后将真机的include文件夹与合并后的.a文件复制到MyLib文件夹中;

      • MyLib文件夹拖入Test_AProject工程中,如下所示:

        Snip20210908_60.png
    Snip20210908_62.png
    • 需要设置Test_AProject工程的配置,如下所示:

      Snip20210908_63.png
    • bulidPhase--> Link Binary with Libraries中必须导入.a文件

    Snip20210908_64.png
    • 然后调用静态库CategoryLib.a中的函数方法,最后调用成功!!!
    Snip20210908_65.png

    参考文章:
    https://blog.csdn.net/shifang07/category_9287774.html?spm=1001.2014.3001.5482

    相关文章

      网友评论

          本文标题:iOS架构之路01 -- 静态库.a文件的制作与使用

          本文链接:https://www.haomeiwen.com/subject/egyewltx.html