Xcode启动参数和环境变量介绍

介绍

这篇文章粗略的介绍一下XCode中Argument/Options模块,经过这两个模块咱们能够在启动app的时候传递一些额外的参数进去,覆盖系统的默认值,来实现特定场景的调试等。json

本篇文章基于XCode10.1版本。markdown

Options

  • Core Location 用来模拟app的位置,能够选择Default Location。app

  • Application Data 能够用于测试CoreData的Scheme迁移。ide

  • Routing App Coverage File 一个GeoJSON文件,对于导航类应用指明所支持的区域。函数

Routing app coverage files are .geojson files which specify the geographic regions supported by your app. The file can have only one MultiPolygon element. MultiPolygon elements consist of at least one Polygon. Polygons contain at least four coordinate points. Polygon start and end coordinate points must be the same.

复制代码
  • Background Fetch 启动由background fetch触发。

我所理解的background fetch为程序在后台时,在不切换到前台的状况下被唤醒。oop

Opportunistically Apps that need to check for new content periodically can ask the system to wake them up so that they can initiate a fetch operation for that content. To support this mode, enable the Background fetch option from the Background modes section of the Capabilities tab in your Xcode project. (You can also enable this support by including the UIBackgroundModes key with the fetch value in your app’s Info.plist file.) Enabling this mode is not a guarantee that the system will give your app any time to perform background fetches. The system must balance your app’s need to fetch content with the needs of other apps and the system itself. After assessing that information, the system gives time to apps when there are good opportunities to do so.

When a good opportunity arises, the system wakes or launches your app into the background and calls the app delegate’s application:performFetchWithCompletionHandler: method. Use that method to check for new content and initiate a download operation if content is available. As soon as you finish downloading the new content, you must execute the provided completion handler block, passing a result that indicates whether content was available. Executing this block tells the system that it can move your app back to the suspended state and evaluate its power usage. Apps that download small amounts of content quickly, and accurately reflect when they had content available to download, are more likely to receive execution time in the future than apps that take a long time to download their content or that claim content was available but then do not download anything.

When downloading any content, it is recommended that you use the NSURLSession class to initiate and manage your downloads. For information about how to use this class to manage upload and download tasks, see URL Loading System Programming Guide.

复制代码
  • Localization Debugging (show non-localized string) 显示没有本地化的字符串。测试

  • Application Language & Application Region 系统语言和区域。fetch

  • XPC Serviceui

  • Queue Debugging 断点this

Argument Passed On Launch

启动参数用来覆盖NSUserDefauls中的默认值,注意这里必须经过Xcode启动App的时候才会起做用,直接点击图标启动是没有用的。

语言

最直接修改语言的方式就是 设置 -> 通用 -> 语言 -> 修改语言,而后重启模拟器,重启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

复制代码

固然也能够在上文提到过的Options中的图形化界面来设置语言。

本地化

若是须要支持多语言,一样的文字在某一种语言中会显示的很长,这个时候能够经过NSDoubleLocalizedStrings来使你的字符串双倍显示:

-NSDoubleLocalizedStrings YES

复制代码

当你完成了本地化,想知道哪些字符串没有被本地化:

-NSShowNonLocalizedString YES

复制代码

开启这个参数,对于没有本地化的字符串,会打印出log,而且在英文环境下,没有本地化的字符串会变成所有大写。

2018-06-09 17:16:23.899756+0800 LaunchArgumentDemo[1592:42786] [strings] ERROR: FlZ-Ch-fUI.text not found in table Main of bundle CFBundle 0x7ffd464002e0 …/Bundle/Application/43466A60-F706-4CCE-A3D5-064C05CD04C6/LaunchArgumentDemo.app> (executable, loaded)

若是是xib/storyboard中的视图,能够 右键 -> Storyboard -> Open As -> Source Code。接着查找log中提到的id:FlZ-Ch-fUI

Core Data

Environment Variable

环境变量的做用与更广一些,它像是App的全局变量,在应用任何地方均可以访问到。

[[NSProcessInfo processInfo] environment]

复制代码

Core Data

若是使用Core Data做本地存储,很难对程序进行追踪。这个时候能够增长日志等级。

log分为1到3,越搞越详细。

-com.apple.CoreData.SQLDebug 3

复制代码

Core Data迁移测试

-com.apple.CoreData.MigrationDebug

复制代码

Environment Variable

对比启动参数,环境变量的做用域更广一些,它更像是App的全局变量,在应用内任何地方均可以访问到。

能够经过如下方式获取到:

[[NSProcessInfo processInfo] environment]

复制代码

dylb

启动时间分为了main函数前,main函数后,XCode能够经过设置环境变量来打印main函数前的几个过程。

经常使用的有两个环境变量。

DYLD_PRINT_STATISTICS

DYLD_PRINT_STATISTICS_DETAILS

复制代码

好比开启DYLD_PRINT_STATISTICS,启动项目,会看到控制台有log打印,就能够知道程序为何启动慢了。

Total pre-main time: 1.1 seconds (100.0%)

         dylib loading time: 434.36 milliseconds (37.1%)

        rebase/binding time: 611.95 milliseconds (52.3%)

            ObjC setup time:  49.24 milliseconds (4.2%)

           initializer time:  73.10 milliseconds (6.2%)

           slowest intializers :

               libSystem.dylib :   3.34 milliseconds (0.2%)

    libMainThreadChecker.dylib :  59.82 milliseconds (5.1%)

复制代码

除此之外,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

复制代码

Zombie

开启Zombie,当对象被释放后,他们仍然在内存里,只不过视图访问将使对象会报错,能够用于调试EXC_BAD_ACCESS。

能够经过环境变量NSZombieEnabled来开启

NSZombieEnabled YES

NSDeallocateZombies YES //僵尸对象的内存会被释放掉

复制代码

Malloc Debug

内存相关的bug一般比较难调试,能够用XCode为咱们提供的malloc debug来调试。

环境变量对应的功能以下:

avatar

MallocStackLogging

记录下内存分配的调用栈,配合debug memory等其余能够获取到对象内存地址的debug技巧,能够很容易地看到一个对象如何被建立。

  • MallocStackLoggingNoCompact的log力度比MallocStackLogging更细一些,功能上相似。

MallocScribble

对于释放的内存,每一个Byte填充成0x55,可以提升野指针的crash率。

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

因为野指针crash可能在对象被释放一段时间后,所以调试有难度。而MallocScribble会在内存释放后,强制覆盖内存,从而提升野指针的crash率。

MallocGuardEdges

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

用的比较少。

MallocGuard

开启Malloc Guard之后,在调试的时候会使用libgmalloc替代malloc,从而当内存出现错误的时候,及时crash你的app。

能够在Diagnostics中开启,也能够经过如下环境变量来开启Malloc Guard

DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib

复制代码

举例:

int *array = malloc(sizeof(int) * 10);

for (int index = 0; index < 30; index++) {

array[index] = index;

}

复制代码

在不开启Malloc Guard的时候,只会crash在main函数,并不会提供有用的信息,可是在开启以后,会crash在对应的行。

这里有一个问题,当index=20时,在某些时候不会crash,不知道是为何,欢迎补充。

自定义

例如当开发一个framework的时候,能够利用环境变量开启一些debug的功能,保证线上环境不受影响。

例如设置Network_Log_Enabled YES,然在代码里读取

NSDictionary * environments = [[NSProcessInfo processInfo] environment];

BOOL logOn = [[environments objectForKey:@"Network_Log_Enabled"] isEqualToString:@"YES"];

复制代码

参考文献

相关文章
相关标签/搜索