登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

编译器之打包动态/静态库 [复制链接]

2016-11-16 21:16
李世铿 阅读:2010 评论:2 赞:4
Tag:  framework编译器二进制动态资源

一、简介

I. 库的类型分类

静态库

  • 以 .a 或 .framework 为文件后缀名
    .a 是一个二进制文件,不能直接拿来用,使用时需要 .a 文件 + 头文件 + 资源文件
    静态库打包时, 只能打包代码 ,图片文件、本地 JSON 文件和 xib 等资源文件无法打包进去
  • 静态库 连接时 完整的复制到可执行文件中,多个文件使用,多份拷贝
  • OC 建议使用静态库,OC 使用动态库审核可能会不通过
  • 静态库无法再包含其他的 .a 静态库。 只能把源码放进去一起编译

动态库

  • 以 .dylib 或 .framework 为文件后缀名「Xcode7 后 .dylib 变为 .tbd 文件」
    .framework 文件,能直接拿来用。 .framework 文件 = 二进制文件(.a 文件 + .h 文件) + 资源文件
    .tbd 文件,只是一个文本文件,其中包含架构信息,以及在真实运行时候二进制所在的位置,以及包含了动态库的符号表还有类的一些信息,这些信息在编译阶段足够了。「减少了所有设备 SDK 二进制动态库的体积」
  • 动态库 运行时 动态加载到内存,只加载一次,多个文件公用,节省内存
  • Swift 只能使用动态库,不支持静态库
  • 大部分第三方库就是动态库,可以暴露出来,放在源码的外部引用使用
  • 动态库的特性使得 软件版本实时模块升级 、应用插件化、etc

II. iOS 设备的 CPU 架构

iOS 库的打包,根据 CPU 架构的不同而不同

架构不同, 不能编译通过

模拟器的 CPU 架构

  • i386:iPhone 4s ~ 5
  • x86_64:iPhone 5s ~ 7 Plus

真机的 CPU 架构

  • armv6:iPhone、iPhone 2、iPhone 3G、iPod Touch「第一代」、iPod Touch「第二代」
  • armv7:iPhone 3Gs、iPhone 4、iPhone 4s、iPad、iPad 2
  • armv7s:iPhone 5、iPhone 5c 「静态库只要支持了 armv7,就可以在 armv7s 的架构上运行」
  • armv64:iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3

二、打包静态库

I. .a 文件 静态库打包

  1. 创建静态库的工程

    创建后执行 运行 或 编译 ,都可以生成静态库「保存在项目的 Products 中」

  1. 通过在不同架构的设备下 编译/运行 生成支持不同架构的静态库

  1. 在 编译/运行 时, 所有项目 都可以设置是 Debug 还是 Release

  1. 设置库的接口 头文件

  1. 通过设置不仅在当前运行的 CPU 架构上,适配所有的机型号架构

    一般 debug = no,release = yes 为了 debug 的时候编译更快「只编译连接当前的 CPU 架构所用的包」

    可以控制 测试版本 和 发布版本 是否都不仅仅能在真机上使用

II. .framework 文件 静态库打包

  1. 前三步和 在 .a 文件 打包方式一致

  2. 设置库的接口 头文件

  1. 设置打包的是 静态库,因为动态库也可以以 framework 的形式存在

    设为Static Library「这个默认选项是动态的」

III. 使用静态库

1. 防止项目中的文件和 静态库的同名文件在运行时会覆盖,只保留一张图片

  • 把图片文件单独的放在一个 .bundle 文件中「一般 .bundle 的名字和 .a 或 .framework 的名字相同」
  • .bundle 文件制作方法:将文件夹,重命名为 XXX.bundle
    同理,其他资源文件也放在一个 .bundle 中

2. 在使用 category 静态库的工程中,调用方法时,会出现找不到该方法的运行时错误: selector not recognized

原因:

  • Unix 的标准静态库实现和 Objective-C 的动态特性之间有一些冲突
  • Objective-C 没有为每个函数定义链接符号,它 只为每个类创建链接符号
  • 当在一个静态库中使用类别来扩展已有类的时候,链接器不知道如何把类原有的方法和类别中的方法整合起来

解决办法:

  • 在使用静态库的工程中配置 other linkerflags 的值为 -ObjC 如果还崩溃,在添加 -all_load 「或者 -force_load 」
  • all_load 作用于所有的库,而 -force_load 后面必须要指定具体的文件
    这样,会将静态库中所有和对象相关的文件都加载进来

3. 避免暴露过多的 .h 文件

使用

  • 在静态库的内部创建一个 .h 文件「一般这个.h文件的名字和静态库的名字相同」
    然后把所有需要暴露出来的 .h 文件名都集中放在这个 .h 文件中,只需要把这个 .h 暴露出来
  • 一般这个总头文件内部引入其他头文件的格式为
    #import <framework名字/其他头文件.h> ,这是以调用这个库的 项目的角度来写的

搜索头文件

  • Header Search Paths

    系统的搜索路径,用来引入项目中 没有添加 的 header 文件

    通过 #import <名称.h> 来引入

  • User Header Search Paths

    用户的搜索路径,用来引入项目中的 已添加 的 header 文件

    通过 #import <名称.h> 或 #import "名称.h" 来引入

  • Always Search User Paths

    Header Search Paths 作为系统级别路径一定会被搜索

    设 Always Search User Paths 为 YES,编译器会先搜索 User Header Search Paths 路径下的目录

    设 Always Search User Paths 为 NO,编译器不会搜索 User Header Search Paths 路径下的目录「默认」

  • 设置格式举例: $(SRCROOT)/项目名称/AppDelegate.h
    $(SRCROOT) 宏和 $(PROJECT_DIR) 宏都指 xxx.xcodeproj 所在的 父目录 ,新建项目后的目录为:

  • Project的 Building Settings 中得设置 默认 并不被 Targets 继承

    只有 Targets 的设置加入了 $(inherited) 时才被继承,添加目录的时候写上 $(inherited) 就表示从 frameworks 里面读取

  • 设置查找路径的参数

    recursive:遍历该目录,编译的时候在找库的路径的时候,会遍历该目录下的所有子目录的库文件

    non-recursive:不遍历该目录「默认,推荐使用,可减少编译速度」

4. 拖拽项目/将项目当做静态库处理

  • 给当前项目在 Link Binary With Libraries 中添加拖拽项目的 库文件
  • 如果当前的 Target 需要依赖其他库文件,在 Target Dependencies 中添加所需的库文件
  • 如果库文件在 Link Binary With Libraries 中已经添加 「必要」 ,但也可能需要在 Target Dependencies 中再次添加 「非必要」

5. 其他

  • 查看静态库所支持的 CPU 架构

    在命令行找到静态库所在的文件夹,执行 lipo -info 静态库文件名 命令

  • 合并静态库

    在命令行找到静态库所在的文件夹,执行 lipo -create 静态库1 静态库2 -output 新静态库名称.a 命令

三、打包动态库

1. 制作、编译过程与静态库相同

2. 在 Embedded Binaries 中添加动态库

Paste_Image.png

3. 合并动态库文件

合并动态库文件并非合并的是 .framework 文件,而是其中的二进制代码文件

4. 动态库的使用注意

I. 自定义的 .a 静态库,不可以包含动态库

II. 自定义的 .framework 静态库,可以包含动态库文件

绕过 Xcode 的 UI 界面来连接动态库,步骤如下

  • 项目中不需要引用连接的动态库「.tbd 的动态库」

  • 通过格式: -l<library_name> 添加动态库,例:添加 libiconv.tdb 记为 -liconv

缺陷

  • 虽然自定义的静态库中已经导入了动态库 X.tbd ,但是,当自定义的 framework 的静态库被调用时,可能需要再次导入动态库 X.tbd 到当前项目中

 

来自:http://www.jianshu.com/p/543965d30c16

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(2)
喵咔 2016-11-18 16:26
赞赞赞赞
回复
xiao66guo 2017-4-12 11:21
不错,给力啊
回复
关闭

每日头条

通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

返回顶部