美文网首页iOS开发iOS程序猿
夯实基础 砥砺前行 ---iOS静态库的开发

夯实基础 砥砺前行 ---iOS静态库的开发

作者: 横爬介士 | 来源:发表于2016-09-07 00:02 被阅读408次

    什么是库?

    库是共享程序代码的方式,一般分为动态库和静态库。

    • 静态库:.a和.framework
    • 动态库:.dylib和.framework

    在实际的项目开发中,经常会使用到库,库分为静态库和动态库两种。和多数人所熟悉的动态语言和静态语言一样,这里的所谓静态和动态是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。

    静态库和动态库区别

    • 静态库:链接时,静态库会被完整的复制到可执行文件中,被多次使用就又多份冗余拷贝
    • 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只会加载一次,多个程序共用,节省内存

    注意:项目中如果使用了自制的动态库(framework)不能被上传到AppStore

    .a和.framewrok有什么区别?

    • .a是一个纯二进制文件,.framework是一个文件夹,文件夹中除了有二进制文件之外还有资源文件。* .a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。* .a + .h + sourceFile = .framework。

    静态库的应用场景

    • 希望更多的开发者在程序中集成,但是又不想公布自己的核心技术;对外暴露统一接口,开发者调用静态库即可。
    • 项目开发中有一部分核心代码,非核心开发人员倘若离职,对于公司来说是一种损失

    1. a静调库的编译

    1.静态库的创建:左侧为.framework 右侧为.a

    1.png

    2.创建工具类,并暴露接口新建工具类,并在buildPhrase中添加需要暴露的.h文件

    2.png

    3.分别在不同的环境下编译,从而得到支持不同环境的静调库

    3.png

    4.查看不同环境下的静态库


    4.png

    在不同的文件夹下可以查看不同环境使用的.a静调库文件,新建项目,将.a文件拖拽到项目中估计可使用

    5.png

    静态库中的架构问题

    当使用真机环境的.a文件在模拟中编译或者运行时,会报架构的错误 。

    • 设备的CPU架构

    • 不同的设备使用的CPU不同

    • CPU的不同就造成使用的CPU架构(即指令集)不同

    • 静态库有其支持的CPU架构

      • 如果静态库在其不支持的CPU架构上面运行就会报错
    • 模拟器使用的CPU架构

    • iPhone4s-iPhone5:i386

    • iPhone5s-iPhone6Plus:x86_64

    • 真机使用的CPU架构

    • iPhone3gs-iPhone4sP:armv7

    • iPhone5-iPhone5c:armv7s

    • iPhone5s-iPhone6plus:arm64

    • 注意: 支持armv7的静态库可以在armv7s上正常使用* 查看静态库的架构(终端命令)
      $ lipo -info 静态库地址

    • 合并静态库
      $ lipo create 静态库1 静态库2 output 合并后的静态库

    如何使静调库支持多种CPU架构

    想要制作的静态库既支持i386架构也支持x86_64架构,有两种解决方法.

    1. 修改静态库的编译环境并重新编译


      6.png

      在termnal中使用命令将多个静态库合并

     $ lipo -create Debug-iphoneos/libStaticLibrary.a Debug-iphonesimulator/libStaticLibrary.a -output libnewstatic.a
    

    合并后的静调库的大小>=合并之前静态库大小之和
    开发环境:需要支持真机以及模拟器的静态库
    生产环境:只需要支持真机的静态库即可

    2 .framework静态库的编译

    第一步与.a文件文件创建一样,选择framework,点开以后发现,项目中已经存在一个与项目名称一样的主头文件(这是苹果推荐的方式 )
    1.将需要暴露的头文件添加到public(拖入即可)

    1.png

    注意:将需要暴露的头文件放到主头文件中
    2.步骤跟.a文件一致,分别在真机以及模拟器环境编译,得到两个不同环境的.framework

    2.png

    3.使用.framework并运行

    3.png

    查看控制台发现报错,发现制作的framework为动态库,动态库的使用,需要在target中手动添加动态库。(只能作为测试使用,苹果禁止自制的动态库上架,上架前切记修改为静态库)
    4.修改编译环境,编译静态库buildsetting 搜索mach 并修改

    4.png

    使用该方法制作的静态库,可以运行,但是在4s中是无法运行的,会报CPU架构的错误,通过$lipo -info StaticFramework查看framework所支持的架构,目前这样制作的framework只支持x86架构,因此4s不能运行** 注意 :**cd 到.framework的路径是不够的,因为仅仅是一个文件夹,真正的静态库是一个二进制文件.因此查看架构信息的时候需要跟这个静态库名字修改架构,使制作的framework支持所有架构

    5.png

    静调库的合并与.a文件一样,在此就不做赘述。至此SDK的开发就到此为止,真正的SDK开发需要在项目中一边开发一边调试

    3 SDK静调库的调试

    单独进行核心代码SDK的开发,开发完成以后需要拖到项目中调试,这样是本末倒置的。SDK的开发需要在项目中调试以及开发。

    6.png

    创建完成以后,项目中的结构发生变化,变化的位置已经已经圈出

    7.png

    在framework文件目录下创建核心代码类,并在项目中需要的地方import主头文件,静调库的制作就不赘述了,与上面的一致。

    4 制作静态库时注意的几点:

    1. 图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。
    2. category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC -all_load

    相关文章

      网友评论

        本文标题:夯实基础 砥砺前行 ---iOS静态库的开发

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