其他分享
首页 > 其他分享> > iOS高级进阶系列之项目开发基础(上)多环境配置,Mach-O与链接器。

iOS高级进阶系列之项目开发基础(上)多环境配置,Mach-O与链接器。

作者:互联网

图怪兽_8ea59bf1ce4b9de81ec691a9278125c8_14887.jpg

前言

最近对项目进行优化,就顺便写一些日常开发中会用到的中高级开发技巧。这篇文章聊一下下面三个内容:多环境配置,Mach-O与链接器,Symbol

多环境配置



聊到多环境配置,我们先说几个概念

352049b252107bb8e3cfdfbb9f1bcc6d.png

上图就是每个项目都存在的,下面解释下红框内的内容:

我尝试加入各种iOS开发交流群,群里的气氛大致就是:学什么iOS,iOS完了,OC完了,群里大致三种人:谁有企业开发证书,马甲包了解一下,至今,大部分iOS开发群还都是仅供吹水用,偶尔能碰见几个好心人解决一下问题,作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:130 595 548,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

我们创建好项目,项目默认两个环境Debug和Release环境,在开发过程中我们也会有两套或者多套服务器环境每个环境的地址不同,粗糙的写法就是如下图所示:

beefde610c43de074733e28ef1ee4e66.png


只能满足两种环境无法适应多环境,下面我们介绍几种多环境配置方法

Targets进行多环境配置

6bcdb77a13fab2669e379c2af4d8621f.png

此时我们只是复制了一个Target,没有产生新的代码,就是复制了一套配置,运行也不会报错

07b833e537a52f1f5e7214c515f12429.png

6c099033a48c12c9a97a9ff831dbc25a.png

这些修改后,就会发现有两个项目可以选择,分别运行后,就会发现有两个App

0e5d9a7aac649b7c2b5c1fd0667c3ab3.png


通过这个我们可以配置不同icon进行区别

42a0bdf4732220f3dd87d035b00462ea.png

我们可以根据项目设置自己相应的

6c983f4e75c556f6f7b957f065d06437.png




配置好后,就可以在项目中进行使用了

cceb1affaf7f390ff98762eca601e496.png

总结

这种多环境配置有一下缺点:

下面我们再介绍比这个更好的方式

Configurations多环境配置



我们知道在Scheme中我们是可以选择环境

4c5731b452983c741a5beb9bb43d7bbc.png



那可以增加新的环境,增加位置如下:

9e2fc2e471e4f09955c7920a243c4d8c.png

它和上面得Scheme是一一对应的



添加完成后再看看Scheme就会发现多了个刚加入的Test

image

image

【问题】:我们每次运行项目都要在上图的Scheme进行切换环境,很不方便,那么有什么办法解决这个问题

8cf2c0cec8da7de63aed3a6b3f8f313f.png

5f525600eda0d978870fdba4980f85fd.png

d7f6561022c36ff705f1878bc874e0d7.png

11b4ee37e3be36f7dabee0a95fec6dc5.png

总结

此时我们就解决了上面你那个问题,但是这种方式还是不够完美,因为项目中要使用cocoapods对第三方管理,此时用上面的方法对Build Settings设置就比较的繁琐,那么有没有一种方法对Build Settings进行集中管理呢?下面我们介绍另一种方式

.xcconfig多环境配置

初始.xcconfig

在使用cocoapods对第三方进行管理,其实就是通过.xcconfig文件进行管理的,创建好cocoapods会自动根据环境帮我们生成好.xcconfig文件

6029069e4050718d8d947b41155a61a6.png


.xcconfig文件内容是已Key-Value形式存在,'='左侧是key值右侧为value值

在项目里会对不同的环境不同的.xcconfig进行绑定

bd56e420e8a3a505a98731fba0e05cd8.png


配置自己的.xcconfig文件

31845f27633dd3a654cf93177af2788d.png

注意命名规则:.xcconfig文件所在的文件夹名称+项目名称+.环境名称

41671096716f770df8ac6833a38623ec.png

74305ef8fcee8dde2457e57fe328e72e.png

使用.xcconfig

我们还想对不同的环境设置不同的请求地址,那么可以再.xcconfig进行设置

27cbc523444a4a8dd8baa1bee78bc2c9.png

678f8e2fdd633566634c430308d60f46.png

58af43d48c8acafb568d3d5a5f2602df.png

f96a3e6e2c2e213569e2cd556b23cc57.png

总结

这种设置方式要比上面的简化了不少,但是.xcconfig文件的功能不只有这些,下面我们扩展一下

.xcconfig扩展

上面我们介绍了简单的配置URL.xcconfig文件是可以配置Build Settings里面的内容,比如我们平时配置动态库,静态库时,要配置到Other Link Flags,通过.xcconfig我们可以直接配置,例如:我们配置AFN

f7bc6994719110105f162508fb7df47b.png


980b82b46785e72f317d18917d9802f8.png

0a18fb0812342eef36899f3f4a62c8a8.png

通过上面的操作我们可以知道,Build Settings的所有配置都是可以通过.xcconfig文件进行管理的。我们来解释下.xcconfig的内容:OTHER_LDFLAGS是Build Settings里面的一个缩写,其它设置缩写是什么呢?

推荐个地址:Xcode Build Settings

90504314b6329c3eca797f3601fda076.png


左侧是对应的Build Settings的Key名称,右边则是其对应的缩写

比如我们想配置Header Search Paths,那么在网页上搜索:Header Search Paths,它对应的缩写:HEADER_SEARCH_PATHS

60f0285e7128191f13f5613176ff865f.png




我们在.xcconfig中配置(随便写的地址)

0e72857e6802ce507ca87ceb00fcc6f0.png



项目Build一下

14c2bd108f8e161a004a32d2c95d373f.png

.xcconfig冲突

问题一

我们项目都会通过cocoapods管理第三方,最开始介绍.xcconfig的时候,说了pods会自动帮我们生成.xcconfig文件,那此时项目中就会有4个.xccongig文件

3fe9e0c67d116fc636a7053647327ecb.png


我们发现一个环境只能配置一个.xcconfig文件,那该怎么办才能让自己写的和pods生成的都能生效呢?

3847cca17fb31f6227e80b753028eaa3.png

发现报警告,警告的意思是设置好了CocoaPods但是项目中你已经设置了其它的.xcconfig文件导致了Pods设置的.xcconfig文件不会生效,我们要解决这个冲突

上面的报错显示了Pods生成的.xcconfig路径:"Target Support Files/Pods-TestOC/Pods-TestOC.debug.xcconfig",我们引入到自己的.xcconfig文件中

a38f46ea590f9417cf4d58fb3a44506d.png


f9e73f0f8c864585a066221c7d7d6f90.png

报错说是找不到Pods生成的.xcconfig,我们查看Pods生成的.xcconfig文件,发现它的根目录是Pods

256608937cb67c637c07fc00d6365b12.png



所以需要改成如下路径:

5e48a7003d3b3a258aaac723b0879e4e.png



再次运行项目,发现就没问题了

bbaad0912028796e0649191e0747e773.png

099b934aca7de776a4aa644cda5eb28c.png

发现Debug模式下不会再报警告,但是Release还会报警告,原因是我们release下的.xcconfig没有配置

问题二

我们看到Pods生成的.xcconfig里也会有OTHER_LDFLAGS,我们自己写的.xcconfig也存在OTHER_LDFLAGS,我们再去看下项目的Other Link Flags,发现Pods生成的.xcconfig没有生效,那么怎么才能让我们写的和Pods生成的都生效呢?

0ddb5e4db157c3262a466b9efa6c551f.png


da3098adda3741c148abbafd90a95915.png

468b29bf86d078242290353b963a58eb.png



我们将AFN给删掉,在VC调用

28899852f0727d93e17f5629c30a10f9.png

0b30f01835ef9f63abf560eff0562794.png

总结

我们通过.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文件



当我们运行项目是,项目会生成一个.app文件

0f4590d1818946df30ac8a5a91ec2a81.png



当我们找到这个.app文件后,显示包内容,里面会有一个可执行文件

78a299f7e9ffbb74a38949bc2beb8325.png

我们可执行文件的调用过程大致如下:

分析Mach-O文件

查看可执行文件有两种方式:

下面我们通过命令行的方式查看可执行文件,其实macho = 文件配置 + 二进制代码 查看Mach-O文件,可以解释项目中的不少问题,我们举几个问题:



因为在Mach-O中已经指定好了项目入口

1d9448e49b7d9d1d80f0509676208705.png

红框内的就是指定入口,同样我们可以通过更换指定入口,来达到更换入口的目的

我们还可以通过Mach-O可以看到一些加载系统依赖的库

c5d6422da6fc26e296def46f17f2d9b3.png


我们发现这个文件展示的内容很多用不到,需要简化一下,上面说了Mach-O是一个可读写文件,所以可以写一个读取Mach-O的文件,来移除这些不必要的东西(怎么写后面文章在说)



下面使用我们写好的读取Mach-O文件再次读取上面的Mach-O文件

03464c45b4b8b39790ebe6da7eb0177b.png

发现少了很多东西,通过这个再次证明Mach-O是可读可写的

链接器

链接的本质



在项目中在编译过程中会生成.o文件(也就是目标文件),如下图所示:

c2f78adbbc2cffa3f362b2e7290da3c4.png

目标文件就是将我们写的代码放到相应的位置,比如我们写的全局变量,代码,全局符号,在编译的过程中会根据不同的特性进行分类

一个项目中会有多个.o文件,而连接的本质就是把多个目标文件组合成一个文件

查看符号

一个项目有很多.m和.h文件,在编译过程中会生成很多的.o文件,那么在合并的过程中我们可以更改暴露给外界的信息吗?

回答这个问题前,我们需要先看到符号表,下面先介绍几个概念:

创建调试Demo

我们先弄个项目,让需要打印的符号信息直接展示在终端,方便我们后面调试。这首先会牵扯到私钥和重定向

f618e02aa0aa061fc85d8df763300e00.png

9e14b417aee9345571e784a01988dcc0.png

红框为终端标识,输入tty,会打印一个像链接一样的东西,这个就是这个终端的位置

897a5f23ea90638bc5a9ff462a9f2ab5.png

代码的意思就是讲打印信息重定向到终端

712b394759dd17893d3f2382614ce0de.png

可以看到终端打印了我们刚才输入的信息

问题一:怎么让Xcode直行我们需要的代码

4af21818514d4faef8fe7d16bea5f670.png

d29faba65485ec2ec2d37aed211ec450.png

94f4e402dc0a8f5d1eddd1c7e172016b.png

我们在.xcconfig上配置的地址就给打印出来了

通过脚本打印

db3611f2174693e07e2f90b00c17048a.png

这个脚本需要三个参数,分别为:CMD,CMD_FLAG,TTY,我们需要在.xcconfig中对这个三个参数进行赋值

58abf2acaa75961ca5c704dea90781b7.png

CMD_FLAG中的-pa的意思:-p是不排序的意思-a是显示所有符号,包含调试符号

7fb8208c3f28fb3aa55eed1404a98619.png

SRCROOT:代表当前代码路径

9475df4970df95a80388f9a3395e2cb7.png

发现打印出来了

82f41da52e835388eaf21d62225a233d.png

再次运行还是会成功

写到最后

文章讲的比较细,写的也比较累,后面可能不会写这么细了!文章中间会牵扯到脚本,后面会写文章聊一下脚本语法。这部分文章实际开发中会有所使用,文章没写完,下篇文章会接着这部分继续讲下去。希望大家能够多多交流,共同进步


标签:文件,进阶,项目,xcconfig,配置,iOS,我们,Mach
来源: https://blog.51cto.com/u_15146321/2716564