iOS静态库和动态库
来源:互联网 发布:linux文件强制锁 编辑:程序博客网 时间:2024/05/18 22:10
iOS静态库和动态库
静态库和动态库是什么,以及它们的区别,详细介绍可参考博文:iOS里的动态库和静态库,里面讲的很详细。
在这里记录下学习的过程
静态库
参考iOS静态库SDK制作(包含第三方静态库)
平时我们用的第三方SDK基本上都是静态库,静态库的几个特点:
- 在App项目编译的时候会被拷贝一份编译到目标程序中,相当于将静态库嵌入了,所以得到的App二进制文件会变大。
- 在使用的时候,需要手动导入静态库所依赖的其他类库。(比如说某个SDK中使用到了
CoreMotion.framework
,在使用的时候需要手动导入。有的SDK需要link十几个系统库,这个时候非常恶心,只能一个一个手动加,这是静态库一个很大的不便之处。)- 导入静态库的应用可以减少对外界的依赖,如果导入的是第三方动态库,动态库找不到的话应用就会崩掉,例如Linux上经常出现的
lib not found
。- 静态库很大的一个优点是减少耦合性,因为静态库中是不可以包含其他静态库的,使用的时候要另外导入它的依赖库,最大限度的保证了每一个静态库都是独立的,不会重复引用。
创建静态库
选择如下的Cocoa Touch Static Library
创建静态库
Build
生成静态库,在Products
文件夹中查看
如果在Edit Scheme
中,Build Configuration
中选择Debug
(以下是我自己的试验)
如果模拟器选择的是
Generic iOS Device
,会有Debug-iphoneos
文件夹如果模拟器选择的是其它的模拟器,会有
Debug-iphonesimulator
文件夹
Debug-iphonesimulator
文件夹下对应的libWZLib.a
是对应模拟器的,可使用lipo -info libWZLib.a
来验证,如:
输出信息如下,其架构为x86_64
input file libWZLib.a is not a fat fileNon-fat file: libWZLib.a is architecture: x86_64
同理可验证Debug-iphoneos
文件夹下的libWZLib.a
,其架构为armv7 arm64
,表示对应真机
如果在Edit Scheme
中,Build Configuration
中选择Release
,可生成其它的2个版本的静态库。Release
表示真实环境,会把日志和断言都去掉。
上面生成的Debug-iphoneos
和Debug-iphonesimulator
文件夹中,头文件WZLib.h
是位于include/项目名
下,如何让头文件,直接在include
文件夹下呢?
在Build Phases
中的Copy Files
中,去掉Subpath
中include/$(PRODUCT_NAME)
,后面的/$(PRODUCT_NAME)
(表示工程文件名)即可:
删除原来生成的文件,Clean之后,再Build,此时头文件就直接在include
文件夹下了
如果想添加多个头文件,选择Copy Files
下的+
号,如下:
静态库使用
如果把对应真机的静态库libWZLib.a
和头文件,导入到项目中使用,则会提示错误:
所以要导入模拟器对应的版本
如果想同时支持模拟器和真机,该怎么做呢?
需要使用终端命令来合并
如下合并命令,表示把libWZLibR.a
(真机版)和libWZLib.a
(模拟器版),合并为test.a
lipo -create libWZLibR.a libWZLib.a -output test.a
此时lipo -info test.a
,显示信息为:
Architectures in the fat file: test.a are: armv7 x86_64 arm64
表示其支持模拟器和真机
要注意的问题
1.如果静态库内有 category
分类,那么需要在添加 -ObjC
编译标识,否则可能会报:unrecognized selector sent to instance
可参考:
- iOS 中静态链接库的使用
- iOS静态库中类的分类问题和符号冲突问题(Xcode other Link Flags)
使用Bundle打包图片配合静态库使用
可参考:
- 使用Bundle打包图片配合静态库使用
- iOS开发之静态库(三)—— 图片、界面xib等资源文件封装到.a静态库
由于静态库只能放代码不能带图片资源,有两种解决方案
- 使用Framework<( ̄︶ ̄)>
- 使用bundle打包图片文件和静态库分别打包拷贝给别人
- 把图片素材传给别人
第三种方法这么坑,万一哪个文件再搞混了….所以推荐用第二种
新建工程:File -> New -> Project… -> OS X -> Framework & Library -> Bundle
我们必须借助于OS X,因为iOS框架中没有创建Bundle的模板
动态库
参考iOS静态库SDK制作(包含第三方静态库)
这个是我们最常用的一类库,使用频率最高的UIKit.framework和Fundation.framework都属于动态库,所有.dylib和.tbd结尾的都属于动态库。动态库的几个特点:
- 平时使用的系统库都放在iOS系统中,在你打包应用程序的时候这些库不会拷贝到你的程序中,当需要使用的时候会动态从iOS系统中加载它们,因为这个原因,动态库也被称作共享库。编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。
- 这些库是所有应用公用的,换一种说法就是节省了应用安装包的体积,这是区别静态库很重要的一个特点,因为静态库使用一次就要拷贝一次,非常浪费资源。
- 动态库在制作的时候可以直接包含静态库,也能自动link所需要的依赖库。
- 使用动态库的时候不需要再次link依赖库,即导即用,这个就厉害了。唯一需要注意的是在导入自己制作的动态库时,需要在
Embedded Binaries
中导入,不然会报错:image not found
。此时这个动态库会跟静态库一样被拷贝到目标程序中进行编译,苹果又把这种Framework叫做Embedded Framework关于动态库要搞清楚一点,我们自己制作的动态库与系统动态库的区别,我们自己制作的动态库引入App项目的时候需要embed进项目,也就是要拷贝到目标程序中,这就有点不像动态库的特性了,苹果这么做也是考虑安全问题吧!
创建动态库
添加相应的类后,在Build Phases
下的Headers
中,把Project
下的头文件移动到Public
即可,如下:
此时build,在工程的的Products
目录下,生成WZFrame.framework
。与静态库一样,也对应真机和模拟器版本
合并真机和模拟器的Framework
1.使用lipo -create
,这种方式比较麻烦一点,生成后还需要替换,具体方式可参考:
- iOS里的动态库和静态库
- iOS创建.a和.framework静态库,以及Bundle资源文件的使用
2.在工程的Build Phases
里添加以下脚本,真机和模拟器都Build
一遍之后就会在工程目录下生成Products
文件夹,里面就是合并之后的Framework
- 新建
New Run Script Phase
添加脚本
if [ "${ACTION}" = "build" ]thenINSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.frameworkDEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.frameworkSIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.frameworkif [ -d "${INSTALL_DIR}" ]thenrm -rf "${INSTALL_DIR}"fimkdir -p "${INSTALL_DIR}"cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"#open "${DEVICE_DIR}"#open "${SRCROOT}/Products"fi
上面的脚本要保证真机和模拟器的framework都要存在,否则生成的framework会为空。此时生成的framework,在项目目录下
此时使用lipo -info WZFrame
,结果为:
Architectures in the fat file: WZFrame are: x86_64 armv7 arm64
表示已合并成功
动态库使用
如果把刚才生成的动态库WZFrame.framework
,导入并调用
#import <WZFrame/WZObject.h>[WZObject testMethod];
添加项目中来直接使用,会出现如下所示的错误
dyld: Library not loaded: @rpath/WZFrame.framework/WZFrame Referenced from: /Users/Miller/Library/Developer/CoreSimulator/Devices/15E3C2C6-797C-40CF-A0F5-8DCA6E472AF1/data/Containers/Bundle/Application/2F13129C-2F69-48BC-B100-00A2D478C4B3/iOSLibTest.app/iOSLibTest Reason: image not found
如何解决呢?
1.选择New Copy Files Phase
2.添加WZFrame.framework
- iOS中的静态库和动态库
- IOS 中的 静态库 和 动态库
- iOS 静态库和动态库
- iOS 静态库和动态库
- iOS 动态库和静态库
- iOS 动态库和静态库
- iOS中的静态库和动态库
- iOS静态库和动态库
- iOS 生成静态库和动态库
- iOS静态库和动态库合并
- ios-静态库和动态库
- iOS静态库和动态库
- 动态库和静态
- iOS关于静态库和动态库的概念
- iOS动态库和静态库的简单使用
- iOS 开发之静态库.a和动态库详解
- iOS静态库和动态库的区别
- iOS静态库和动态库的区别 升级版
- android实现第三方QQ登录
- 自学框架知识的较好的入门视频分享
- 正式版TBSA 6.0(用来分析多层及高层建筑结构的专用程序)
- 如何才能真正的提高自己,成为一名出色的架构师?
- 如何实现对象的排序Comparable
- iOS静态库和动态库
- 字符串C++的封装CString
- ImportError: libicui18n.so.56 and/or libicui18n.so.58 when importing cv2
- HashMap深度解析(一)
- 在JSP页面转换时间格式
- 第8周【项目2
- 第十四周项目1验证算法
- ubuntu16.04 安装CUDA 8.0 和 cuDNN 5.1 /cudnn6.0,可适用于gpu版本的(tensorflow,caffe,mxnet)
- 根据极验官网集成的一些坑,集成时间2017.11.21