系列文章:iOS高级进阶
前言
本篇文章学习的主要内容为:多环境配置,xconfig文件冲突解决,Mach-O与链接器,符号的种类与作用,strip命令
一、多环境配置
- Project:包含了项目所有的代码,资源文件,所有信息。
- Targets:对指定代码和资源文件的具体构建方式。
- Scheme:对指定Target的环境配置。
我们创建好项目,项目默认两个环境Debug和Release环境,在开发过程中我们也会有两套或者多套服务器环境,每个环境的地址不同,粗糙的写法就是如下图所示:
1 | #if DEBUG |
它只能满足两种环境,无法适应多环境,下面我们介绍几种多环境配置方法
(一)Targets进行多环境配置:
1.在项目时可以创建多个Target,复制一个target,成为新的dev_target
2.修改一下新的target 的 bundle Id
3.修改一下新的target的info.plist文件
4.两个target 都可以运行,并且是不同的项目,可以通过 配置不同 的icon 进行区分
5.在build setting 中 设置宏
5.1 OC宏配置
5.2 swift 宏配置
1 | //开发环境 |
6.总结
这种多环境配置有一个缺点: 会存在多info.plst文件,环境多了,配置会比较乱
(二)对指定Target进行多Schems的环境配置,进行不同的环境编译:
1.在Project中,首先添加需要的 Configuraction
2.创建不同的schems,指定他们的Build Configuraction
3.在build setting 中 设置宏
1 | //开发环境 可编译不同的请求地址 |
4.这样可以愉快的开发了
总结:这种方式虽然不会存在多info.plst文件,但是环境多了,配置会比较乱, 修改的代码都在一起,影响主工程代码(这里可以开分支开发,不污染主分支,最后合并代码)
(三).xcconfig多环境配置:
初始.xcconfig
xcconfig文件正如其名字一样,就是xcode里的config文件。 我们在开发过程中,需要配置一些参数,这些都可以在xcode工程的setting对项目进行配置,xcconfig就是将这些配置项以文件的形式独立出来,方便共享与配置。比如两个项目用到相同的配置,那么只需要在xcode中选择对应的xcconfig文件即可,方便与灵活共,我们经常使用的 cocoapods 对第三方进行管理,其实就是通过.xcconfig文件进行管理的,创建好cocoapods会自动根据环境帮我们生成好.xcconfig文件。
.xcconfig文件内容是已Key-Value形式存在,’=’左侧是key值,右侧为value值
1、创建config文件
注意命名规则:.xcconfig文件所在的文件夹名称+项目名称+.环境名称
2、编辑文件内容:
3、回到Project中,将配置文件和schems 关联起来
4、在info.plist中,配置
5.需要在 Build Settings
中的 User-Defined
添加 自定义宏定义
6、在项目中简单使用
1 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
总结:这种设置方式要比上面的简化了不少,但是.xcconfig文件的功能不只有这些,下面我们扩展一下
二、xconfig扩展与文件冲突解决
(一).xcconfig扩展
上面我们介绍了简单的配置URL
,.xcconfig文件
是可以配置Build Settings
里面的内容,比如我们平时配置动态库,静态库
时,要配置到Other Link Flags
,通过.xcconfig
我们可以直接配置
,例如:我们配置AFN
- 在.xcconfig中写如下代码
1 | HOST_URL=127.0.0.1 |
- 项目build之后,在
Build Settings
中查看Other Link Flags
,发现写的已经配置进去了 - 过上面的操作我们可以知道,
Build Settings
的所有配置
都是可以通过.xcconfig
文件进行管理
的。我们来解释下.xcconfig的内容:OTHER_LDFLAGS是Build Settings里面的一个缩写
,其它设置缩写是什么呢? - 推荐个地址:Xcode Build Settings
- 比如我们想配置
Header Search Paths
,它对应的缩写:HEADER_SEARCH_PATHS
(二).xcconfig文件冲突
问题一
我们项目都会通过cocoapods管理第三方
,最开始介绍.xcconfig的时候,说了pods
会自动帮我们生成.xcconfig文件
,那此时项目中就会有4个.xccongig文件
,直接运行会报错
解决办法:在我们自己的xccongig文件中,通过 #include
引入cocoapods的xccongig文件
1 |
|
问题二
我们看到Pods生成的.xcconfig
里也会有OTHER_LDFLAGS
,我们自己写的.xcconfig
中也存在OTHER_LDFLAGS
,我们再去看下项目的Other Linker Flags
,发现Pods
生成的.xcconfig没有生效
,那么怎么才能让我们写的和Pods生成的都生效呢?
使用
inherited
进行集成1
2
3
4
5
6
7
8
9
10
#include "Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig"
HOST_URL = 127.0.0.1
// ld
// key-value
// OTHER_LDFLAGS 缩写
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"
HEADER_SEARCH_PATHS = /use/info/inclue
总结
我们通过.xcconfig
对项目进行配置
,我们可以通过.xcconfig+Scheme
方式进行统一管理,这样既省时,又省事。
三、Mach-O与链接器
Mach-O初识
【Mach-O定义】:Mach-O(Mach Object)
是macOS、iOS、iPadOS存储程序和库
的文件格式
。对应系统通过应用二进制接口
(application binary interface,缩写为ABI
)来运行该格式的文件
。
Mach-O格式
用来替代BSD系统
的a.out格式
。Mach-O文件
格式保存
了在编译过程和链接过程
中产生
的机器代码和数据
,从而为静态链接
和动态链接
的代码提供
了单一文件格式
。
查看项目的Mach-O文件
1、当我们运行项目是,项目会生成一个.app文件
2、右击查看包内容,会发现里面有个可执行文件,这个就是mach-o文件
3、通过 file
命令来查看MachODome
文件类型(这里用的真机,所以是arm64
架构。)
执行文件的调用过程大致如下:
1.调用fork
函数,创建一个process
2.调用execve
或其衍生函数,在该进程上加载,执行我们的Mach-O
文件 当我们调用时execve
(程序加载器),内核实际上在执行以下操作:
- 1.将文件加载到内存
- 2.开始分析
Mach-O
中的mach_header
,以确认它是有效的Mach-O
文件
分析Mach-O文件
Mach-O组成
1. Mach-O 结构:
Mach-O
的主要组成部分:Mach Header
、Load Command
、Data(__TEXT、__DATA、符号表)
2. Mach Header
Mach Header
里有 Mach-O
的CUP
信息,以及Load Command
的信息。可以使用 otool
或 objdump
命令来查看
- otool命令:
otool -v -h MachODome
- objdump命令:
objdump --macho --private-headers MachODome
下面就是使用objdump命令,查看的详情结果如下:在改文件中已经指定好项目入口,和已经需要引用的系统依赖库信息:
3. Load Command
Load Command
包含 Mach-O
里的命令类型信息,名称和二进制文件的位置
(类似一本书的目录)。同样可以使用 otool
或 objdump
命令来查看
- otool:
otool -v -l a.out
- objdump:
objdump --macho --private-headers MachOApp
(注意这里是 headers) - 结果如下:
4. Data
Data
由 Segment
的数据组成,是 Mach-O
占比最多的部分,有代码有数据,比如符号表(类似一本书的具体内容)。
Data
共三个 Segment
,__TEXT、__DATA、__LINKEDIT
。其中 __TEXT
和 __DATA
对应一个或多个 Section
,__LINKEDIT
没有 Section
,需要配合 LC_SYMTAB
来解析 symbol table
和 string table
。这些里面是 Mach-O
的主要数据。
使用 xcrun size
命令来查看 Data
内容的分部
- xcrun size 命令:
xcrun size -x -l -m MachOApp
- 结果如下: