以下是学习动态库和静态库的过程中自己整理的笔记:
首先一点,什么是库?
对于iOS开发而言库分为两种,
1.一种是开源库,这个相比大家都知道的,如app中盛传的AFNetworking,SDWebImage等.
2.另一种叫做闭源库,iOS开发人员都知道苹果是闭源的,所谓的闭源就是其库中的方法和属性只能拿来使用,但是并不能
查看类中具体的实现,很多大牛或者第三方也会一这种形式提供给开发者闭源库.
闭源库有哪些?其使用目的是什么?
1.闭源库分为静态库和动态库,其存在的形式是类的.m文件生成的二进制文件
2.公司或者个人开发有些核心的技术,而且不想让其他的人看到具体实现核心技术的内容的时候使用,为了方式信息的泄露
静态库和动态库?使用上的区别?
静态库:在使用静态库的工程中引用静态库以后,在执行的过程中静态库会被多次拷贝到可执行文件中,在同一设备在不同的app进行
拷贝的话会出静态库冗余的现象
动态库:在使用动态库的工程中引用动态库以后,链接的时候不复制,动态库在系统中,加载一次可供多个程序调用
区别:创建和编译库的方式大体一样,但是静态库编译以后生成的库和头文件不在同一个目录,需要手动添加:
动态库目录:
添加方式:
添加一点料:xcode6之前使用动态库的app是不允许上传到appstore的
资源打包:
命名为项目名称.bundle
带有资源的静态库打包,我们需要将资源全部添加到Bundle文件中,为了防止文件重复,更好的管理文件资源,防止用户使用的时候发生文件冲突,怎么打包bundle文件,新建文件夹,命名为项目名称,把资源文件放到该目录下,最后,把文件名称后面添加一个.bundle的后缀
注意,默认的静态库编辑是不会将bundle一起编译进去的,所以这个文件夹需要我们手动添加到使用静态库的工程中去
静态库的制作和使用:
在制作静态库的时候创建工程如下图:
在模拟器环境和真机环境下编译生成不同环境下的静态包:
(当编译以后红色的小房子会变成灰色)
问题点: cpu框架不支持错误如下图:
在i386这种架构下找不到这两个头文件
由于静态库是二进制文件,它适配特定的架构环境,
每一个手机都有属于自己的架构,不同CPU采用的是不同的CPU架构。 任何一个静态库都有它支持的CPU架构,如果是跑在不支持的CPU架构上面,那么就会报错。比如基于iPhone 6sPlus的架构来创建的静态库,如果运行在4s上 就会报错。修改Build Settings -- >Build Active Architecture Only 为NO 就解决了这个问题。
不同模拟器或者真机下的cpu框架:
模拟器的架构:
在4s-5c i386架构
在5s-现在 x86_64
真机:
3gs-4 armv7
4s-5c armv7s
5s-6s arm64
解决方法:
需要修改Build Settings中的 Build Active Architecture Only 以满足运行不同CPU环境的模拟器。 将此设置为NO。
在不同编译环境下编译会生成四种静态库,debug模拟器,debug真机,release模拟器,release真机,我们需要将运行环境调至不同的状态并生成如上四种形式的静态库。这里只以一种情况为例:
- 设置是Debug还是release
选择Edit Scheme--> Buid Configuration设置为release
在真机和模拟器环境下command+b以后会生成下面的四个文件:
查看静态库支持的cpu框架:
终端执行命令:lipo -info 静态库的文件名或者目录
alendeMacBook-Air:~ alen$ lipo -info /Users/alen/Library/Developer/Xcode/DerivedData/CustomTexTextField-hbhkvlyjlfjidgbqrpxivirdehyc/Build/Products/Debug-iphonesimulator/CustomTexTextField.framework/CustomTexTextField
如何将模拟器和真机的静态库进行合并:lipo -create 真机环境的静态库.a 模拟器环境的静态库.a -output 静态库名.a
alendeMacBook-Air:~ alen$ lipo -create Debug-iphoneos/lib01-MakeStaticLibrary.a Debug-iphonesimulator/lib01-MakeStaticLibrary.a -o bothSupportStatic.a
-
如果编译的静态库中有分类的话必须在 Build Settings --> Other Linker Flags中加 -Objc 如果还崩溃,还得加上 -all_load
1.制作、编译的过程与静态库相同,只不过创建工程的时候选择的是framework库。
2.注意:动态库可以使用但是不能上架! 而且使用的时候必须在添加动态库的工程中的 General-->Embedded Binaries 中添加一下或者如第三条设置为静态库,具体如图所示:
3.那么如何想使用动态库上架呢? 我们只需要在制作的时候将其编译成静态库。在Buid Settins-->Mach-O Type--> Static Library具体如图:
4.同样不要忘了编译,这样编译出来的库就是静态库了。我们就可以像静态库一样在工程中使用了
合并动态库:
这里有个注意点就是,我们所要查看和合并的并不是xxx.framework,而是xxx.framework目录下的xxx,以下图为例,我们想要查看或合并的文件就是libframework,对这个文件进行操作就可以了。
alendeMacBook-Air:~ alen$ lipo -create Debug-iphoneos/CustomTexTextField.framework/CustomTexTextField Debug-iphonesimulator/CustomTexTextField.framework/CustomTexTextField -o CustomTextField
将真机下的静态库文件进行替换,使用的时候拖入该文件的动态库即可
cp IJKMediaFramework Release-iphoneos/IJKMediaFramework.framework/
合并动态库简便方法:
我们可以在xcode中添加一个共同体aggregate,然后添加编译脚本来实现。
参照原文:http://www.jianshu.com/p/04a7e28f11b9
在工程中点击上方工具栏File->New->Target,在选项中选择Other中的Aggregate,命名最好和工程名有关,我这里就写成JRDataModelAggregate。
新建好以后,选择targets列表下的JRDataModelAggregate,点击build phases,点击+新建一个New Run Script Phase,把下面的脚本复制到shell下的选项中(脚本来源自网络,感谢这段脚本的原作者)。有能力的可以根据自己的需要修改下面的脚本。
# Sets the target folders and the final framework product.
#如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
#例如: FMK_NAME = "MyFramework"
FMK_NAME=${PROJECT_NAME}
# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration"Release"-target"${FMK_NAME}"-sdk iphoneos clean build
xcodebuild -configuration"Release"-target"${FMK_NAME}"-sdk iphonesimulator clean build
# Cleaning the oldest.
if [ -d"${INSTALL_DIR}"]
then
rm -rf"${INSTALL_DIR}"
fi
mkdir -p"${INSTALL_DIR}"
cp -R"${DEVICE_DIR}/""${INSTALL_DIR}/"
# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create"${DEVICE_DIR}/${FMK_NAME}""${SIMULATOR_DIR}/${FMK_NAME}"-output"${INSTALL_DIR}/${FMK_NAME}"
rm -r"${WRK_DIR}"
open"${INSTALL_DIR}"
复制完以后,点击左上角运行旁边的target(上图左上角那个黄色的选项),在下拉的列表中选中我们刚才创建的JRDataModelAggregate,command+B编译一下,如果没什么意外,等到编译成功便会弹出我们编译好的framework了。