iOS 制作静态库

制作静态库

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

两者区别*:动态库时在程序运行时动态链接的,且可以被多个程序链接,相当于以动态库为中心,系统只会加载动态库到内存一次,这样动态库就始终只占一份内存,而静态库是提前把需要编译的实现文件编译为二进制文件,每个程序都需要复制一份,这是在使用静态库就决定了的特性,我们需要把静态库复制到工程文件内,供我们程序使用,而在制作时静态库时,我们可以选择暴露哪些文件给使用者,当然大部分都只需暴露头文件,我们当然也可以暴露实现文件,供我们参考学习,了解其中原理,众使我们修改了该文件的内容也没关系,因为该文件已经在制作静态库时已经编译成二进制文件,我们使用时不会再次编译该文件,资源文件如图片等也是可以我们替换,因为编译时只是简单的COPY,所以我们可以替换SVProgressHUB里的error或success成我们个性化的图片。苹果官方不允许我们App包含动态库。

.a.framework的区别:
制作.a 都需要我们手动在Header Search Paths加头文件搜索路径
制作 .framework不需要

制作.framework静态库

我们先说.framework 的制作过程,我们新建项目选择iOS的framwork / library ,建好后默认有一个头文件,这不是我们需要的,直接删掉,这里我们可以任意建文件夹和文件,把我们需要的功能库搭建好后,我们在Build phase > Headers > public 内添加我们需要暴露的文件,这样我们就建好了,然后我们分别选着模拟器 和 Generic iOS Device 来构建我们的product ,只有当我们构建完Generic iOS Device才能看到product内的target由红色变为黑色,这说明文件存在,构建完毕,然后我们右键 show in finder 找到编译好的文件,当然,这个文件只包含armv7 和arm64 架构的。我们还需要在Mach-type修改类型为Static Library,当然我们也可以制作动态库,只是不能发布。如果你制作动态库就需要在Embedded Binaries 内添加库。

对于这几种CPU架构分类:

真机:

3gs ~ 4s :armv7

5 ~5c :armv7s

5s~ 6plus:arm64

模拟器:

4s~5 : i386

5s~6plus : x86_64

所以我们需要合并这几种包,并且都是debug包,我们一般发布给别人Release包,这需要我们Edit Scheme 选择Run > info >build configuration 为Release。Release包会比debug包要小一点,因为编译时作了代码优化,运行效率会高一点,但不会明显提高。

为了保证都能运行,我们还需要合并包,这里的包是.framework 文件里的同名的无扩展名的二进制文件,使用下面命令合并,更多使用方法( man lipo

lipo -create test1 test2 -output test3

然后替换之前任意一个同名的二进制文件,这里多次强调同名,因为系统就是根据根据静态库名在静态库内寻找二进制文件,不然会报找不到该文件的错误。

这样我们直接把替换二进制文件后的.framework文件拖进我们其它工程直接使用。

当然如果我们还需要在静态库内使用资源文件,我们使用Bundle,在该项目内Add Target ,选择OSX 内的Bundle,我们需要删除一系列,修改sdk,修改product name等等。

制作.a静态库

类似制作.framework静态库,我们新建项目XHQ_StaticFramework,选择Cocoa Touch Static Library
这时可以看到两个文件夹:XHQ_StaticFrameworkProduct , Xcode 为我们自动建好的XHQ_StaticFramework(.h/.m)文件,一般我们只需要头文件,头文件写下我们所有需要公开的头文件,其它全部删掉,以便客户使用时只需引入这个头文件。Product存放我们生成的二进制文件。这里我们引入<UIKit/UiKit.h>框架,(网上多个版本都提到需要在Build Phrases >Link Binary With Libraries 内添加UIKit.framework,但是作者没有添加也能正常使用,如果你知道原因请告诉我,谢谢!)

我们在XHQ_StaticFramework 文件夹下建好我们自己的代码库后,把需要公开的头文件加到Build Phases >Headers ,如果你没有这个目录,你需要手动Editor > Add Build Phases> Add Headers Build Phases 来添加。(提示:如果无法选择,你需要点击Build Phases 空白处后再重复上面的步骤。)

点开 Headers 默认是有三个文件目录: public&&private&&project, 其中pulic和private都是放对外公开的文件,两者区别就是存储的路径可能不一样,我们可以在Packaging> Private/Public Headers Folder Path设置路径。这里我们设置为include/$(PROJECT_NAME),project 存放我们私有的文件。

然后我们需要在Build Settings设置一些值:

Dead Code Stripping > NO(去掉不会执行到的代码)

Strip Style > Debugging Symbols

Strip Debug Symbol During Copy > NO(去掉Debug相关符号)

Strip Linked Product > NO

这样做是为了后期产生bug时,我们能通过符号文件定位到我们需要的类的信息, 但是如果是iOS 或者 OSX则配置完全相反。相关文章

我们编译成功后就可以正常使用。使用时我们有两种方式

一种是在其它项目中拖进该项目,在新项目中添加依赖 Build Phases > Target Dependencies添加.a静态库,然后就是link library 内添加.a静态库;

上面的方式适合我们自己内部使用,好处就是可以动态的修改静态库的文件,Xcode会根据是否需要重新编译来生成静态文件,而其实我们可以是直接使用生成的.a静态库和包涵头文件的include文件夹,只不过我们每次都需要配置Search Headers Paths,这种方式适合给外部使用。

使用脚本生成集成包

相信上面的这些分别生成支持不同架构的包已经让你精疲力竭,我们有更加方便的方法制作通用的包,那就是使用脚本来构建支持多个架构的包.首先我们在前面制作framework的基础上添加
Aggragate target,然后在Build Phases 内添加 Run Script
把下面代码添加进去。直接运行,然后生成的包目录会自动打开。

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}"

参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容