1、动态库 & 静态库

  • 什么是库:

    • 库是程序代码的集合,是共享程序代码的一种方式。根据源代码的公开情况,库可以分为 2 种类型:

    • 开源库:

      • 公开源代码,能看到具体实现。

      • 比如 SDWebImage 、 AFNetworking

    • 闭源库:

      • 不公开源代码,是经过编译后的二进制文件,看不到具体实现。

      • 主要分为:静态库、动态库

  • 静态库和动态库:

    • iOS 中静态库和动态库的存在形式:

      • 静态库:.framework 和 .a
      • 动态库:.framework 和 .tbd(之前叫 .dylib)
    • 静态库和动态库在使用上的区别:

      • 静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝。

      • 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。

    • 使用注意:

      • 需要注意的是项目中如果使用了自制的动态库,不能被上传到 AppStore,审核无法通过。

      • 从 iOS 7.0 开始,如果程序中使用到 Framework,不再需要添加引用,只需要 import 头文件就可以了,Xcode 会在编译的时候,自动添加相关的引用。

      • 但是 .dylib 和 .tbd 动态库还是需要手动添加引用。

2、iOS 设备的架构

  • 模拟器:

    • iPhone4s-iPnone5:i386
    • iPhone5s-iPhone7 Plus:x86_64
  • 真机:

    • iPhone3gs-iPhone4s:armv7

    • iPhone5-iPhone5c:armv7s

    • iPhone5s-iPhone6s:Plus:arm64

    • 支持 armv7 的静态库可以在 armv7s 上正常运行。

3、.a 静态库的制作

  • 1、创建工程.

    • 先创建一个新的 Xcode 工程 Test,需要选择下面 Cocoa Touch Static Library 这个模板:

    • 创建完成后是这个样子的:

  • 2、创建文件。

    • 我们把默认生成的 Test.h 和 Test.m 删掉,重新创建一个类 PrintString,在这个类里面添加一个单纯打印字符串的简单方法:

  • 3、添加公开的头文件。

    • 为了让使用者知道有哪些方法可以用,我们需要公开头文件,这里我们公开PrintString.h,将需要公开的头文件添加到 TARGETS => Build Phases => Copy Files 中。

  • 4、设置支持所有架构。

    • 我们需要把 Build Active Architecture Only 修改为 NO,否则生成的静态库就只支持当前选择设备的架构。在 TARGETS => Build Setting => Architecture => Build Active Architecture Only 处修改。

  • 5、编译生成静态库文件。

    • 我们分别选择 Generic iOS Device 和任意一个模拟器各编译一次,编译完后,我们会看到工程中 Products 文件夹下的 libTest.a 由红色变成了黑色,然后 show in finder,看看生成的文件:

    • 我们看到它为真机和模拟器都生成了 .a 静态库。里面都包含我们选择公开的头文件。

    • 我们来看看静态库支持的框架,命令为:

      	$ lipo -info 静态库名字

    • 我们看到,Debug-iphoneos 里面的静态库支持的架构有 armv7 和 arm64 所以它只能用于真机,在模拟器上会报错。Debug-iphonesimulator 里面的静态库支持的架构有 i386 和 x86_64,所以它只能用于模拟器,在真机上会报错。

  • 6、合并真机和模拟器静态库文件。

    • 如果想要让模拟器和真机通用一个静态库,我们可以使用终端命令来实现。命令格式为:

      	$ lipo -create 第一个.a文件的绝对路径 第二个.a文件的绝对路径 -output 最终的.a文件路径

    • 我们看到生成了一个新的 libTest.a 文件。这个静态库就支持所有模拟器和所有真机了。然后我们创建一个文件夹,把 .a 和头文件都放进去,我们最终需要使用的就是这个文件夹:

    • 注意:为了开发方便,我们可以使用生成的通用静态库,但是最终上线的使用我们可以只导入真机的,这样工程的体积也会小一些。

  • 7、使用生成的 .a 静态库。

    • 新建一个工程,将上面的通用静态库拖进去,导入头文件,就可以使用里面的方法了。经过试验,我们生成的静态库在真机上和模拟器上都能成功打印字符串:

4、.frameworke 静态库的制作

  • 1、创建工程.

    • 先创建一个新的 Xcode 工程 LibTest,需要选择下面 Cocoa Touch Frameworke 这个模板:

    • 创建完成后是这个样子的,我们可以看到,工程本身自带一个 LibTest.h 文件和一个 Info.plist 文件。

  • 2、创建文件。

    • 我们创建一个类 PrintString,添加一个单纯打印字符串的简单方法:

  • 3、添加公开的头文件。

    • 为了让使用者知道有哪些方法可以用,我们需要公开头文件,我们需要在 LibTest.h 文件中引入需要公开的头文件,并且将 TARGETS => Build Phases => Headers 中的 Project 中要暴露的头文件拖拽到 Pulic 里面,这里我们公开 PrintString.h :

    • 注意:暴露出来的头文件中 import 的其他类也得添加到 public 中暴露出来。如果不想将 import 的类暴露出来,那么在头文件中用 @class 然后在对应的 .m 文件中再 import。

  • 4、设置支持所有架构。

    • 我们需要把 Build Active Architecture Only 修改为 NO,否则生成的静态库就只支持当前选择设备的架构。在 TARGETS => Build Setting => Architecture => Build Active Architecture Only 处修改。

  • 5、设置生成静态库。

    • 因为动态库也可以是以 framework 形式存在,所以需要设置,否则默认打出来的是动态库。将 TARGETS => Build Setting => Linking => Mach-o Type 设为 Static Library(默认为 Dynamic Library):

  • 6、编译生成静态库文件。

    • 我们分别选择 Generic iOS Device 和任意一个模拟器各编译一次,编译完后,我们会看到工程中 Products 文件夹下的 LibTest.framework 由红色变成了黑色,然后 show in finder,看看生成的文件:

    • 我们看到它为真机和模拟器都生成了 LibTest.framework 静态库。

    • 我们来查看静态库支持的框架,命令为:

      	$ lipo -info framework下的二进制文件名字

    • 我们看到,Debug-iphoneos 里面的静态库支持的架构有 armv7 和 arm64 所以它只能用于真机,在模拟器上会报错。Debug-iphonesimulator 里面的静态库支持的架构有 i386 和 x86_64,所以它只能用于模拟器,在真机上会报错。

  • 7、合并真机和模拟器静态库文件。

    • 如果想要让模拟器和真机通用一个静态库,我们可以使用终端命令来实现。framework 静态库合并的不是 framework,而是 framework 下的二进制文件 LibTest,命令为:

      	$ lipo -create 第一个framework下二进制文件的绝对路径 第二个framework下二进制文件的绝对路径 -output 最终的二进制文件路径

    • 我们看到生成了一个新的 LibTest 文件,然后将任何一个 framework 中的二进制文件替换成合并后的二进制文件,然后把 framework 添加到要使用的项目中即可使用。

  • 8、使用生成的 .framework 静态库。

    • 新建一个工程,将静态库拖进去,导入头文件,就可以使用里面的方法了。经过试验,我们生成的静态库在真机上和模拟器上都能成功打印字符串:

    • 注意:如果静态库中有 category 类,则在使用静态库的项目配置 TARGETS => Build Setting => Linking => Other Linker Flags 中需要添加参数 -ObjC 或者 -all_load。如果创建的 framework 类中使用了 .tbd,则需要在实际项目中导入 .tbd 动态库。

5、运行调试静态库

  • 如果你是开发静态库的人,你会发现上面的方法只是制作静态库,并没有办法运行看效果和调试 bug,这时候我们可以这样.

  • 1、创建工程。

    • 新建一个专门用来开发静态库的正常工程 Test:

  • 2、添加静态库的 target。

    • 添加一个静态库的 target。

    • 我们看到它生成了几样东西:

      • 一个 framework 的 target:在这里面修改静态库的配置们,例如支持的架构、要暴露的头文件们和 Mach-O 的配置。
      • 一个 LibTest 文件夹:静态库里面的类们都放在这里面。
      • Products 文件夹下面的 LibTest.framework:在这里 show in finder 找到编译后生成的静态库。
  • 3、开发调试代码

    • 向 LibTest 中添加文件,并设置要暴露的头文件们、支持的架构和 Mach-O 的配置。

    • 在 Test 中引入头文件和测试代码,编译运行,我们看到程序可以正常运行,并可以在动态库里面断点运行,方便我们调试。

  • 4、编译生成静态库文件。

    • 确保代码没问题后,选择对应的 target 编译生成静态库文件。

  • 5、后面的过程就与上面一样了。

iOS - Library 库的更多相关文章

  1. iOS - 静态库的创建与使用

    在日常项目开发中,不论是为了两个公司项目上的业务交流还是为了减少项目的编译时间,有的时候我们会把项目中的私密内容打包成静态库,或者是把项目中变动较少一部分打包成静态库以便提高编译效率,那么下面我们就来 ...

  2. iOS静态库.a文件制作和导入使用

    iOS静态库.a文件制作: 1.新建Cocoa Touch Static Library工程 新建工程 - 选择iOS-FrameWork&Libary,选择 Cocoa Touch Stat ...

  3. fir.im Weekly - 2017 年必须了解的 iOS 开源库

    放假的脚步临近,每个人都在期待一个愉悦的春节假期.最近,@张嘉夫 分享了一篇 Medium 上的文章<33 个 2017 年必须了解的 iOS 开源库>,总结了 2016 年最棒的 iOS ...

  4. iOS链接库的冲突

    最近在打包的时候,遇到一个坑.特此记录一下 起因是发现 Unity 5.4 版本,使用c#写的下载,下载速度无法突破 2M/s,同样的网络,后来横向对比使用原来 Cocos2d 开始的游戏,可以达到 ...

  5. iOS 第三方库、插件、知名博客总结

    iOS 第三方库.插件.知名博客总结 用到的组件 1.通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FMDB 本地数据库组件 SDWebImage 多个缩略图 ...

  6. iOS静态库的制作与引用

    [iOS静态库的制作与引用] 1.Configuring Exported Headers To configure which headers are exported to clients, se ...

  7. iOS 静态库,动态库与 Framework

    iOS 静态库,动态库与 Framework     静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢 ...

  8. iOS静态库转Framework动态库

    参考文章: iOS静态库(.a 和framework)  XCode6制作动态及静态Framework  说说iOS中静态库的开发  dyld: Library not loaded: @rpath/ ...

  9. iOS静态库相关-封装lib

    来源:http://blog.csdn.net/zsomsom/article/details/9163635 Library介绍 基本知识 在实际的编程过程中,通常会把一些公用函数制成函数库,供其它 ...

随机推荐

  1. Error:Unsupported major.minor version 51.0 .

    替换了项目jar文件Tomcat运行报错, 项目开发环境jdk1.6,替换jar文件编译环境是1.7 修改eclipse java ->compiler和Installed JREs 重新编译替 ...

  2. log4j.properties 配置的学习整理

    参考资料: log4j.properties:用来做什么的(日志) Log4j:由2部分组成 :loggers(记录器)            ----日志的类别 appender(输出源)     ...

  3. Rectangle Area || LeetCode

    把交叉点的坐标求出来即可. #define max(a,b) ( (a)>(b)?(a):(b) ) #define min(a,b) ( (a)<(b)?(a):(b) ) int co ...

  4. CSS之border-radius

    1.圆角设置 CSS3圆角只需设置一个属性:border-radius(含义是"边框半径").你为这个属性提供一个值,就能同时设置四个圆角的半径.所有合法的CSS度量值都可以使用: ...

  5. iOS 1-2年经验面试参考题

    Model层: 数据持久化存储方案有哪些? 沙盒的目录结构是怎样的?各自一般用于什么场合? SQL语句问题:inner join.left join.right join的区别是什么? SQLite的 ...

  6. mongoose升级后遇到的问题

    由于想在mongoose中使用Q,所以将mongoose升级到了4.1.0,而线上mongoDB的版本是2.6.7,升级的时候,node-modules存在mongoose的残渣,所以调用 npm i ...

  7. ios-自定义alertView提示框

    先上图,弹框的背景色,按钮背景色,提示的消息的字体颜色都可以改变 利用单例实现丰富的自定义接口 // // PBAlertController.h // PBAlertDemo // // Creat ...

  8. Adding Swagger to Web API project

    Adding Swagger to Web API project. All source code for this series can be found here. When you creat ...

  9. erlang httpc

    1,set proxy 10.100.1.76 :8888 httpc:set_options([{proxy,{{"10.100.1.76",8888},[]}}]). 2,se ...

  10. 亚马逊如何变成 SOA(面向服务的架构)?

    阮一峰 日期: 2016年9月10日 上一篇文章,我摘录了<程序员的呐喊>.这本书有趣的内容太多,今天再摘录一段. 1. 亚马逊公司不仅是世界最大的网络书店,还是世界最大的云服务商.它是怎 ...