美文网首页IOS知识积累
XCode启动参数和环境变量配置

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

作者: 司空123 | 来源:发表于2019-10-12 17:51 被阅读0次

    当我们使用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

    相关文章

      网友评论

        本文标题:XCode启动参数和环境变量配置

        本文链接:https://www.haomeiwen.com/subject/nliqmctx.html