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"];

複製代碼

參考文獻

相關文章
相關標籤/搜索