1. 对 库 格式的探究
2. 对framework 格式的探究,什么是Embed
3. 通过Workspace 实现测试工程
4. dyld 对动态库 查找流程探究 @roath分析
5. 解决冬天哭路径问题
6. 动静态库的链接
复制代码
1. 静态库 和 动态库 区别
最大的区别:
链接方式:(动态链接 、 静态链接)
编译产物:
静态库: 只编译产生 .o 文件的合集
如何链接:静态库.o + App.o => app exec (App的可执行文件)
动态库:
编译产生 .o => 进一步链接 => 最终产生的链接产物(动态库 + 可执行文件)
如何链接:
动态库 和 可执行文件 同级,动态库 -> 在运行的时候 ->通过 路径 + 加载 动态库 (不允许上架)
动态库是允许上架的, 动态库是 framework 格式的, 在于 签名,不能路径替换动态库 实现热更新
动态库(dylib、framework)
如何设置动/静态库:
1. build Settings: Mach-O Type : Dynamick Library 或者 static Library
2. Podfile : use_frameworks! 动态 #use_frameworks! 静态
复制代码
2.动静态库的链接
-
动态库 链接 静态库
已知 cocospods 导入的是源码,编译组件的源码, .xcconfig 文件,当前buildSetting,设置编辑器和链接器的参数,通过文件控制buildSetting 主工程 -> header -> public 组件 -> header -> public 复制代码
-
动态库链接静态库:
App + 动态库组件(引用 「静态库」 ) 分析: 动态库 -> .o 经过链接 产生 可执行文件exec 静态库 .o + app.o => app . exec 动态库 .o + 静态库.o => 链接 产生 动态库 复制代码
问题:符号冲突
app内
void cat_test(){
nslog(@"cat_test111");
}
库内
void cat_test(){
nslog(@"cat_test222");
}
动态库, 编译链接的过程中冲突的
编译 、 运行 正常
复制代码
动态库 二级命名空间 -> 当访问符号是 先访问动态库 再访问符号。 再到符号。二级命名空间默认开启
静态库:编译 、 运行 正常
独立的.o 与 app.o 有重名 就冲突
为什么没冲突。
(已知 分类 是动态创建)
ld- 链接静态库 只链接用到的代码,用不到的不链接。没有import文件不会冲突
xcfonfig 配置 -all_load
dumplicate symbol for archive
静态库符号冲突 产生,解决:冲突的符号一个 加前缀
- 静态库 链接 静态库
App -> (静态库A (静态库B))
App使用 静态库A组件,引用了静态库B
报错undefined B-方法
方法 1
链接成功;
- header (api)
- 库path xcconfig library_search_path =
- 库名称 xcconfig OTHER_lDFLags =
方法2
静态库合并 静态库.o文件的合集
App -> (静态库A .o 静态库B .o)
- 动态库 链接 动态库
App -> (动态库A (动态库B))
App运行时使用, 通过路径。
报错: dyld 工具
dyld:Library not loaded
…
Reason: image not found
App 连接 动态库 A 没问题, A链接 动态库B 访问异常
@Rpath
@executable_path 表示可执行程序所在目录
@loader_path mach_o
3. 动态库的 – 反向依赖 :-> 向上依赖 A upword dependency
App使用组件代码,组件里面使用App的代码
原理:真正调起动态库 是在运行的时候,去查找符号,
复制代码
- dyld :将app的 和 动态库的 间接符号 放到一个位置,
- 编译过程中 编译成二进制 + 符号分类(没有分配虚拟内存地址),
- 在链接时 将符号表合并。
所以 动态库也可以通过dyld 去App里查找符号
App内 ZZAppObject.h
如何实现:
xcconfig:header_search_path = {SRCROOT}/../XXAPP/”
此时可以查找到
动态库A 定义符号 [[XXAppObject new] testApp];
此时就无法编译 undifine
如何处理
动态库 添加忽略, 运行起来自己处理
OTHER_LDFAGS = (inherited) -Xlinker -U -Xlinker _OBJC_CLASS_XXAppObject
(-U 标记符号 动态查找符号,使dyld 查找动态库和App的镜像)
复制代码
4. 其他
-
动态库的符号 ( 懒加载和 非懒加载)不会影响编译,用到去search
-
oc的动态性体现在 1. 动态创建 2. mach-o 类通过 dylb runtime
-
比较
1. 动态库为什么会影响启动速度,dyld 通过path 加载 动态库(耗时),
2. App体积:大,
3. 共享缓存:
1. 静态库快,是因为与APP结合一起,
2. App体积:小,链接器 在 链接静态库 时,扫描如果App没有使用到,
可以在链接时不加载(按需加载)
3. 共享缓存
复制代码
符号
App在上架时要脱符号,除了间接符号 干掉(全局符号、本地符号)。
动态库 (调试符号、本地符号) 除了全局符号 都可以干掉
静态库
build Setting => Strip Style
App 的 – ( All symbols ) 除了间接符号 干掉(全局符号、本地符号)。
动态库的 Non-Global symbol 除了全局符号 其他的全部脱掉
静态库的 Debuging symbol 只脱掉 debug 符号
*静态库 比 动态库 大的是 链接之后的产物