XCode启动参数和环境变量配置

当我们使用Xcode调试app的时候,会传递一些额外的参数进去,覆盖系统的默认值,从而实现特定场景的调试。主要手段就是配置启动参数和环境变量.
全部的配置分布在Info Arguments options Diagnostics四个板块中

一 首先Info板块:

  1. build configuration :构建运行模式
设置运行模式`Debug`还是`Release`
也可以自定义构建环境,但依然区分`Debug`还是`Release`
  1. debug process as: 调试角色
是当前用户发起的调试行为还是root行为
  1. launch :启动时机
`Automatically`:自动启动运行
`Wait for executable to be launched` : app处于等待状态,当点击图标或者收到push notification才会启动。
用于调试app启动前的逻辑

二 首先Arguments板块: 启动参数&环境变量

启动参数:Argument Passed On Launch :

配置启动参数 用来覆盖NSUserDefaults中的默认值。启动参数只有在通过XCode启动App的时候才会起作用,直接点击图标启动是没用的

1.AppleLanguages可以用来设置启动的语言
更改语言最直接的方式就是:设置 -> 通用 -> 语言 -> 修改语言,然后重启模拟器,接着重启App,这个过程是很繁琐的。

利用启动参数,这个过程变得非常的直接,比如,设置App在简体中文下启动

-AppleLanguages (zh-Hans)
一些常见的语言列表如下:

English (U.S.)              en
English (UK)                en-GB
English (Australian)        en-AU
English (Indian)            en-IN
French                      fr
Spanish                     es
Portuguese                  pt
German                      de
Italian                     it
Chinese (Simplified)        zh-Hans
Chinese (Traditional)       zh-Hant
Japanese                    ja
Korean                      ko
Russian                     ru

2.实现本地化

当你的App需要同时支持多语言的时候,本地化变得很重要。同样的文字,可能在某一中语言中会显示的很长,这时候你可以先通过NSDoubleLocalizedStrings来看看你的UI在双倍显示当前字符串的时候的样子:

-NSDoubleLocalizedStrings YES

检查哪些字符串没有被本地化

-NSShowNonLocalizedStrings YES

开启这个参数,运行项目,对于没有本地话的字符串,会打印出log,并且在英文环境下,没有被本地话的字符串会变成全部是大写的:

  1. 输出Core Data跟踪日志

当你使用Core Data作为本地持久化存储的技术栈时,你会发现很难对程序进行跟踪,这时候可以使用启动参数

-com.apple.CoreData.SQLDebug 3

log等级分为1到3,越高越详细

4.Core Data迁移调试

-com.apple.CoreData.MigrationDebug
  1. 日志语法高亮
    想让调试语句更加突出吗? 可以使用如下的颜色混合日志参数
-com.apple.CoreData.SyntaxColoredLogging YES

屏幕快照 2019-10-12 下午4.56.12.png
环境变量: Environment Variable

通过代码获取环境变量

[[NSProcessInfo processInfo] environment]
  1. DYLD : 优化过App启动时间的同学都知道,启动时间分为main前和main后,XCode可以通过环境变量来打印main函数前的几个过程.

常用的有两个环境变量:

DYLD_PRINT_STATISTICS
DYLD_PRINT_STATISTICS_DETAILS
屏幕快照 2019-10-12 下午5.03.53.png

再运行应用,会发现log打印,然后你就知道哪里拖慢了你的应用启动:

         dylib loading time:  26.31 milliseconds (26.5%)
        rebase/binding time:   1.03 milliseconds (1.0%)
            ObjC setup time:  10.59 milliseconds (10.6%)
           initializer time:  61.15 milliseconds (61.6%)
           slowest intializers :
             libSystem.B.dylib :   5.57 milliseconds (5.6%)
   libBacktraceRecording.dylib :   3.18 milliseconds (3.2%)
    libMainThreadChecker.dylib :  30.87 milliseconds (31.1%)
                         ZBank :  34.67 milliseconds (34.9%)

  total time: 1.0 seconds (100.0%)
  total images loaded:  372 (365 from dyld shared cache)
  total segments mapped: 20, into 449 pages with 48 pages pre-fetched
  total images loading time: 747.41 milliseconds (73.6%)
  total load time in ObjC:  10.59 milliseconds (1.0%)
  total debugger pause time: 721.09 milliseconds (71.0%)
  total dtrace DOF registration time:   0.10 milliseconds (0.0%)
  total rebase fixups:  373,831
  total rebase fixups time:   9.04 milliseconds (0.8%)
  total binding fixups: 544,195
  total binding fixups time: 186.19 milliseconds (18.3%)
  total weak binding fixups time:   0.76 milliseconds (0.0%)
  total redo shared cached bindings time: 194.97 milliseconds (19.2%)
  total bindings lazily fixed up: 0 of 0
  total time in initializers and ObjC +load:  61.15 milliseconds (6.0%)
                         libSystem.B.dylib :   5.57 milliseconds (0.5%)
               libBacktraceRecording.dylib :   3.18 milliseconds (0.3%)
                libMainThreadChecker.dylib :  30.87 milliseconds (3.0%)
                                     ZBank :  34.67 milliseconds (3.4%)
total symbol trie searches:    1239212
total symbol table binary searches:    0
total images defining weak symbols:  37
total images using weak symbols:  100

除此之外,dyld还有很多可以用来调试的环境变量

DYLD_FRAMEWORK_PATH
DYLD_FALLBACK_FRAMEWORK_PATH
DYLD_VERSIONED_FRAMEWORK_PATH
DYLD_LIBRARY_PATH
DYLD_FALLBACK_LIBRARY_PATH
DYLD_VERSIONED_LIBRARY_PATH
DYLD_PRINT_TO_FILE
DYLD_SHARED_REGION
DYLD_INSERT_LIBRARIES
DYLD_FORCE_FLAT_NAMESPACE
DYLD_IMAGE_SUFFIX
DYLD_PRINT_OPTS
DYLD_PRINT_ENV
DYLD_PRINT_LIBRARIES
DYLD_BIND_AT_LAUNCH
DYLD_DISABLE_DOFS
DYLD_PRINT_APIS
DYLD_PRINT_BINDINGS
DYLD_PRINT_INITIALIZERS
DYLD_PRINT_REBASINGS
DYLD_PRINT_SEGMENTS
DYLD_PRINT_STATISTICS
DYLD_PRINT_DOFS
DYLD_PRINT_RPATHS
DYLD_SHARED_CACHE_DIR
DYLD_SHARED_CACHE_DONT_VALIDATE
  1. Zombie:

开启Zombie,当对象被释放后,他们仍然在内存里,只不过视图访问僵尸对象会报错,可以用于调试EXC_BAD_ACCESS。
可以通过环境变量NSZombieEnabled来开启

NSZombieEnabled YES

也可以选择NSDeallocateZombies,这样僵尸对象的内存会被释放调。

NSDeallocateZombies YES
屏幕快照 2019-10-12 下午5.25.27.png
  1. MallocDebug

内存相关的bug是很难调试的,幸运的是XCode为我们提供了一系列工具,这组工具就是malloc debug。
环境变量对应的功能如下:

20180630125224801.png

MallocStackLogging

记录下来内存分配的调用栈,配合memory debugging等其他可以获取到对象内存地址的debug技巧,可以很容易的查看到一个对象是如何被创建的

MallocScribble

对于释放的内存,每个Byte填充成0x55,能够提高野指针的crash率。

原理:
以OC对象为例,对象被释放后,内存被标记为回收,
但是在第二次写入前,内存还是之前的OC对象;
这就导致了即使对象被释放了,
只有内存被覆盖后的野指针访问才会crash。

对于开发者来说:野指针的crash很有可能是在对象被释放一段时间后,给调试带来了难度,而MallocScribble会在内存释放后,强制覆盖内存,提高野指针的crash率。

MallocGuardEdges
在分配大内存的时候,在内存前后添加额外的页,进行内存保护。

MallocGuard
开启Malloc Guard后,在调试的时候会使用libgmalloc替换malloc,从而在当内存出现错误的时候,及时crash你的App。
可以通过以下环境变量来开启MallocGuard:

DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib

在不开启malloc guard的时候,会crash在main函数,并不会提供有用的信息,在开启malloc guard后:

20180630125300902.png

4.自定义环境变量

除了系统的启动参数和环境变量之外,也支持自定义参数。

我们都知道NSUserDefaults可以用来存储用户的配置信息,比如有一个配置信息是AllowCellularNetwork,即是否允许蜂窝移动网络下访问网络,这时候就可以测试在用户不同设置的情况下启动:


20180630125317414.png

当开发一个framework的时候,可以利用环境变量来开启一些debug功能,这样能保证线上环境不受影响。


20180630125336145.png

然后,在代码里读取

NSDictionary * environments = [[NSProcessInfo processInfo] environment];
BOOL logOn = [[environments objectForKey:@"Network_Log_Enabled"] isEqualToString:@"YES"];

options板块:

Core Location用来模拟App的位置
Application Data 可以用于测试CoreData的Scheme迁移
Routing App Coverage File 一个GeoJSON文件,对于导航类应用指明App支持的区域
GPU Frame Capture GPU帧率检测
Background fetch 表示启动由backgroud fetch触发
Show non-localized strings 显示没有本地话的字符串
Application Language & Application Region 系统的语言和区域
options 中的部分配置可以通过配置环境变量来实现

四. Diagnostics (诊断)板块:

1.Runtime Sanitization运行时调试选项:
启用运行时检查以检测并避免代码中的错误。
Enable Address Sanitizer

// 跟踪代码中的内存冲突。

Thread Sanitization

审核代码中的线程问题。

undefined behavior sanitizer 可在运行时检测未定义的行为

undefined behavior sanitizer可以在运行时检查未定义的行为。
对性能的影响很小,在Debug配置中平均有20%的CPU开销。
未定义的行为包括:整数溢出,无效的布尔枚举值,被零除等
  1. Runtime API Checking 运行时API检查

Main Thread Checker 主线程检查
当使用Xcode调试器运行应用程序时,主线程检查器将自动启用。

从后台线程检测对AppKit,UIKit和其他API的无效使用。
  1. Memory Management内存管理
    同环境变量配置的内容交叉,在这里可以更加直观的配置.
    开启一些内存管理相关的服务,包括内存涂抹,边缘保护,动态内存分配保护,僵尸对象等等
Malloc Scribble          // 内存涂抹 用0xAA填充分配的内存,用0x55填充释放的内存。

Malloc Guard Edges       // 内存边缘保护
Guard Malloc             // 动态内存分配保护
Zombie Objects           // 僵尸对象

Malloc Scribble的基本思想是,在对象被释放后,在对应内存块中填上不可访问的无意义的数据(0x55),那么我们再使用这个对象时,程序将直接Crash

  1. Logging后台日志

malloc stack // malloc堆栈日志
Dynamic Linker API Usage // 记录动态链接器API调用(例如,dlopen)。
Dynamic Linker Loads // 记录加载的动态库

参考链接:https://blog.csdn.net/Hello_Hwc/article/details/80865787

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

推荐阅读更多精彩内容

  • 转载自:Launch Arguments &Environment VariablesXcode中的启动参数和环境...
    夏天的风_song阅读 2,268评论 0 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 那日蒋姐来到三诊室,诉说自己肩颈紧绷绷的,膝关节轻微疼痛.问诊后,她除了肩颈不适之外,只偶有胸闷,心慌等症状. 躺...
    立新七针李丽霞阅读 1,127评论 2 11
  • 这个春节的天气特别温暖,太阳每天都笑嘻嘻的露脸,似乎在告诉人们,春节快乐! 忙碌的人们又该启程为生活奋斗了,于是雨...
    占晓雪阅读 211评论 0 1
  • IoC控制反转 控制(对象的生命周期)反转(对象的控制权给IoC容器)(Inversion of Control)...
    _羊羽_阅读 213评论 0 1