转载自:Launch Arguments &Environment Variables
Xcode中的启动参数和环境变量中,有许多的选项可以传递给target的scheme,开启一些有用的调试特性。
要在应用中使用启动参数和环境变量,在Xcode工具栏中选择你的target然后点击“Edit Scheme...”
在左侧的面板中,选择 “Run[AppName].app”,然后在右侧选择 “Arguments” 选项卡,下面会出现两个可下拉的部分,分别是 “Arguments Passed on Launch” 和 “Environment Variables”。
从调试一个应用的target这个目的来看,启动参数和环境变量可以认为是相同的——它们都是通过定义一些值来改变应用的运行时行为。在实践中,这两者的主要区别是,启动参数一个以横线(-)大头,并且没有单独用于参数值的字段。
启动传参
任何启动时传递的参数在运行期间会覆盖掉当前NSUserDefaults 中的值。这个特性可以被用于特定领域的测试和调试工作,不过使用最广泛的场景还是在本地化和Core Data。
本地化
本地化本身是一项非常具有挑战性而且耗费时间的工作。幸运的是,有一些启动参数可以让这个过程变得容易很多。
想了解更多有关本地化的信息,可以查看我们关于 NSLocalizedString
的文章。
NSDoubleLocalizedStrings
为了模拟德语中经常被破坏UI而且不会被空格折行的长复合词(类似 götterdämmere Weltanschauung),于是有了 NSDoubleLocalizedStrings 这个选项。
根据 IBM 的国际化指南,在把英语翻译成很多欧洲语言的时候,文字的长度可能会变成原来的二倍乃至三倍。
Number of Characters in Text | Additional Physical Space Required |
---|---|
≤ 10 | 100% to 200% |
11 – 20 | 80% to 100% |
21 – 30 | 60% to 80% |
31 – 50 | 40% to 60% |
51 – 70 | 31% to 40% |
70 | 30% |
当你在等待第一批翻译工作完成的时候,或者你只是想看看多语言环境下UI到底被破坏成什么样子,指定下面这个启动项:
-NSDoubleLocalizedStrings YES
NSShowNonLocalizedStrings
在完成本地化工作的时候,经常会有忘记本地化的字符串。这个时候,如果你使用了 NSShowNonLocalizedStrings 这个启动选择,所有没有被本地化的字符串全都会变成大写,多么美妙!
-NSShowNonLocalizedStrings YES
AppleLanguages
所有启动参数中最有用的大概是AppleLanguages。
一般情况下,要想更改系统语言环境需要经过设置-通用-语言与地区iPhone语言
,然后等待模拟器或者设备重启。现在使用下面这个简单的启动参数就可以完成同样的事情:
-AppleLanguages (es)
AppleLanguages 的值可以是语言的名称("Spanish"),也可以是语言的编码(es)。考虑到本地化文件是使用 ISO 639 编码来定位的,因此使用编码比使用语言名称要好一些。
ISO_639-1代码表
Core Data
在所有的系统框架当中,Core Data可能是最依赖于调试的。各种 Managed objects 在 context 和 thread 中传来传去,各种通知来回发送,发生的事情太多,以至于很难一直对程序进行跟踪。这时候就需要下面这些至关重要的启动参数了:
SQL调试
大部分Core Data技术栈使用SQL作为持续存储层,如果你的应用和大部分应用都类似的话,你可以在Core Data工作的时候观察SQL语句和统计信息。
设置下面这个启动参数“:
-com.apple.CoreData.SQLDebug 3
然后运行程序
CoreData: sql: pragma cache_size=1000
CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOR, t0.ZTITLE, t0.ZCOPYRIGHT FROM ZBOOK t0 ORDER BY t0.ZAUTHOR, t0.ZTITLE
CoreData: annotation: sql connection fetch time: 0.0001s
CoreData: annotation: total fetch execution time: 0.0010s for 20 rows.
com.apple.CoreData.SQLDebug 接收的值在 1 到 3 直接,值越高代表输出会越详细。
日志语法高亮
想让你的调试语句更加炫酷一些?把 com.apple.CoreData.SyntaxColoredLogging 这个选项也扔进去,然后做好被各种颜色轰炸的准备:
-com.apple.CoreData.SyntaxColoredLogging YES
迁移调试
在其他的持久层当中,迁移数据是一件易事。然而出于某种原因,Core Data成功地吧这件事变成了噩梦。当事情发展和预期不符,你没有别人可以去责备,只能默默埋怨自己的无知,你感觉自己确实不配使用这样一个直观的,经过良好设计的图形持久化框架
时,有一个选项可以帮到你:
-com.apple.CoreData.MigrationDebug
环境变量
启动参数是针对可执行文件的,环境变量的应用范围更广泛一些,和全局变量有类似的地方。
使用下面几个设置来配置环境,通过定制内存管理策略来帮助调试程序。
除非特别声明,环境变量通过传递 YES 和 NO 来打开和关闭某个特定功能。
Zombie!
僵尸在媒体上被过度渲染,在 Objective-C 里却没有得到足够的重视。不管怎样,每个人都知道,要想了解僵尸是需要付出一定的代价的。
当对象被释放之后,它们会被“僵尸化”,是它们能够继续接受消息。这个特性可以用于追踪运行时出现的EXC_BAD_ACCESS 异常。
Name | Effect |
---|---|
NSZombieEnabled | If set to YES, deallocated objects are 'zombified'; this allows you to quickly debug problems where you send a message to an object that has already been freed. |
NSDeallocateZombies | If set to YES, the memory for 'zombified' objects is actually freed. |
内存分配器
内存分配器包含了几个可以通过环境变量打开的调试选项。苹果在Memory Usage Performance Guidelines 中解释道:
Guard Mallock 是一个特殊版本的 malloc 库,在调试时会替换掉标准库的实现。Guard Malloc 使用了若干技术,可以让你的应用在内存错误发生的时候崩溃掉。例如,它在不同的虚拟内存页上分配多个分开的内存块,然后当内存被释放掉的时候,删除掉整个内存页。之后企图访问被释放掉的内存时,会直接造成内存异常,而不是随便获取一块儿可能含有其他数据的内存区域。当崩溃发生时,你可以直接在调试器中检查失败的位置,定位具体的问题。
下面是最有用的几个选项:
Name | Effect |
---|---|
MallocScribble | Fill allocated memory with 0xAA and scribble deallocated memory with 0x55. |
MallocGuardEdges | Add guard pages before and after large allocations. |
MallocStackLogging | Record backtraces for each memory block to assist memory debugging tools; if the block is allocated and then immediately freed, both entries are removed from the log, which helps reduce the size of the log. |
MallocStackLoggingNoCompact | Same as MallocStackLogging but keeps all log entries. |
I/O 缓存
尽管可能性不大,你还是可能会碰到,一些情况下你需要让 stdout 中的日志以非缓冲模式输出(确保在前一个输出被打印出来之后再打印下一个)。你可以通过设置 NSUnbufferedIO 环境变量做到这一点:
Name | Effect |
---|---|
NSUnbufferedIO | If set to YES, Foundation will use unbuffered I/O for stdout (stderr is unbuffered by default). |
你还是可以通过苹果的 Technical Note TN2239: iOS Debugging Magic 和 Technical Note TN2124: OS X Debugging Magic 获取更多的有关内容(同时学习到 一堆的 runtime 内部知识)。
希望这篇文章里展示的秘密知识能够持续地为你所用。聪明地使用它们,并且把它们传递给你的同事吧,就像散播那些都市传奇和八卦谣言一样。