mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 04:17:17 +00:00
update: content update
This commit is contained in:
@@ -2425,7 +2425,7 @@ import 举个例子吧。在 `Person.m`
|
||||
|
||||
### 编写工具生成 hmap 文件
|
||||
|
||||
#### 为什么要编写 hmap 文件
|
||||
#### 为什么要生成 hmap 文件
|
||||
|
||||
如果2个 `.m` 文件有相同的头文件代码,造成编译浪费。
|
||||
|
||||
@@ -2458,7 +2458,7 @@ Xcode 会主动生成 `.hmap` 文件,那为什么还需要研究生成 `hmap`
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/StaticLibUseHeaderMapOnlyQuoteMethod.png" style="zoom:30%" />
|
||||
|
||||
分析:在 App 使用 Static Library 的情况下,假设开启了 `Use Header Map`,静态库中所有头文件类型为 `Project`(只有 Project、Private、Public 3种类型,public 就是字面意思的公开,p r)的情况,最终生成的 `.hmap` 文件中只会包含类似 `#import "Student.h"` 的键值引用。也就是说使用的地方,只有 `#import "Student.h"` 的这种方式才会走 hmap 策略,否则还是走 `Header Search Path` 来寻找头文件路径。
|
||||
分析:在 App 使用 Static Library 的情况下,假设开启了 `Use Header Map`,静态库中所有头文件类型为 `Project`(只有 Project、Private、Public 3种类型,public 就是字面意思的公开,private 则代表 In Progress, project 才是通常意义上的 Private 含义)的情况,最终生成的 `.hmap` 文件中只会包含类似 `#import "Student.h"` 的键值引用。也就是说使用的地方,只有 `#import "Student.h"` 的这种方式才会走 hmap 策略,否则还是走 `Header Search Path` 来寻找头文件路径。
|
||||
|
||||
组件、库使用 `#import <SomeFramework/SomeFrameworkExportedHeader.h>` 是访问的标准做法。好处有3点:
|
||||
1. 明确头文件的由来,避免歧义
|
||||
@@ -2505,7 +2505,7 @@ LLVM 真是好东西,把 Xcode 编译、链接等一些幕后的事情变成
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/StaticLibUseHeaderMapEffect.png" style="zoom:30%" />
|
||||
|
||||
可以看到静态库使用了自定义的 Header Maps 文件后,使用静态的 App 前后,编译耗时减少了0.1s。
|
||||
可以看到静态库使用了自定义的 Header Maps 文件后,使用静态的 App 前后,编译耗时减少了1.1s,节省了57%。
|
||||
|
||||
|
||||
|
||||
@@ -2696,6 +2696,37 @@ objdump --macho --private-headers DSYMDemo
|
||||
|
||||
|
||||
|
||||
### main 函数
|
||||
|
||||
实验一:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/MainFuncHasNoDifferenceWithOthers.png" style="zoom:30%" />
|
||||
|
||||
编写2个函数,main 函数和 test 函数,除了方法名不同,在汇编侧是一样的。
|
||||
|
||||
实验二:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/CanNotLinkWithoutMainFunc.png" style="zoom:30%" />
|
||||
|
||||
可以看到创建的 `test.c` 文件中,只有一个 `test` 方法。没有 `main` 方法,然后用 gcc 发现链接报错。
|
||||
|
||||
然后利用 gcc 指令 ` gcc -nostartfiles -e_test test.c` 发现可以编译通过,运行也没问题。
|
||||
|
||||
当然除了 gcc,很多嵌入式平台,可以在代码中指定 c 程序的起点。
|
||||
|
||||
比如 STM32,专门有个汇编文件,用于系统的初始化。
|
||||
|
||||
总结一下:
|
||||
|
||||
- main 函数和其他普通函数并无区别
|
||||
- main 函数是很多程序的默认起点,但绝不是非它不可,任何函数都可以被设置成程序起点。
|
||||
|
||||
|
||||
|
||||
iOS 侧,dyld 默认以 main 函数作为函数起点。
|
||||
|
||||
|
||||
|
||||
### dyld 加载过程
|
||||
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/dyldFullProcess.png" style="zoom:40%" />
|
||||
|
||||
Reference in New Issue
Block a user