Xcode開發(fā)選項設(shè)置與調(diào)試工具

構(gòu)建測試平臺

獲取隱藏的文件信息改衩,在終端輸入如下命令:

defaults write com.apple.Finder AppleShowAllFiles TRUE 
defaults write com.apple.Finder Showpathbar -bool true
defaults write com.apple.Finder _FXShowPosixPathInTitle -bool true
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
chflags nohidden ~/Library/

通過上述設(shè)置,F(xiàn)inder中的所有文件都變?yōu)榭梢娖缢拢ㄒ浴?”開頭的隱藏文件钞脂。此外還會顯示詳細的文件路徑和擴展信息揣云,最為重要的是能看到與用戶相關(guān)的Library目錄,iOS模擬器和Xcode的數(shù)據(jù)都存儲在此目錄下冰啃。

chflags命令將那些蘋果認為會迷惑用戶的隱藏文件全部顯示了出來邓夕,例如/tmp或/usr。這樣更方便查看模擬器目錄阎毅。

把$SIMPATH添加到Finder的側(cè)邊欄焚刚,便于訪問。默認設(shè)置下扇调,F(xiàn)inder沒有$SIMPATH矿咕。想要實現(xiàn)上述設(shè)置,在終端輸入以下命令:

cd ~/Library/Developer
open .

Developer文件夾下有三個目錄狼钮。其中CoreSimulator碳柱、Xcode是我們常用的。將Developer拖拽到Finder側(cè)邊欄中燃领。

屏幕快照 2017-03-26 下午12.33.07.png

Xcode構(gòu)建設(shè)置

首先將警告視為錯誤士聪。大部分警告都是由clang產(chǎn)生的锦援,它屬于Xcode編譯器的前端(frontend)猛蔽,值得認真對待。這樣做可以減少代碼復雜度灵寺、確保語法正確曼库,還可以捕獲那些難以發(fā)現(xiàn)的錯誤,比如無符號問題或是格式字符串漏洞略板,看如下代碼:

- (void)validate:(NSArray *)someTribbles withValue:(NSInteger)desired{
    if(desired > [someTribbles count]) {
        
    }
}

NSArray的count方法返回一個無符號整形(NSUInteger)毁枯,if判斷語句會提示 “'NSInteger' (aka 'long') and 'NSUInteger' (aka 'unsigned long'”警告。啟用將警告視為錯誤的選項叮称,從而使clang標記該類型為bug种玛,運行工程將會失敗。

這里的意思是說啟用項目構(gòu)建配置中的更多警告模式瓤檐,并將警告提升到bug的高度赂韵,強迫自己盡可能在開發(fā)的早期階段解決掉一些隱患,培養(yǎng)良好的編碼習慣挠蛉。

在target->build setting->Warning Policies下祭示,把Treat Warnings as Errors 設(shè)置為YES。

屏幕快照 2017-03-26 下午1.06.59.png

在Custom Compiler Flags下谴古,設(shè)置Other Warning Flags质涛,這里有-Wall稠歉、-Wextra、-Weverything三個值可選汇陆,含義如下:

  • -Wall 并不是所有警告怒炸。這一個警告組開啟的是編譯器開發(fā)者對于“你所寫的代碼中有問題”這一命題有著很高的自信的那些警告。要是在這一組設(shè)定下你的代碼出現(xiàn)了警告瞬测,那基本上就是你的代碼真的存在嚴重問題了横媚。但是同時,并不是說打開Wall就萬事大吉了月趟,因為Wall所針對的僅僅只是經(jīng)典代碼庫中的為數(shù)不多的問題灯蝴,因此有一些致命的警告并不能被其捕捉到。但是不論如何孝宗,因為Wall的警告提供的都是可信度和優(yōu)先級很高的警告穷躁,所以為所有項目(至少是所有新項目)打開這組警告,應(yīng)該成為一種良好的習慣因妇。

  • -Wextra 如其所名问潭,-Wextra組提供“額外的”警告。這個組和-Wall組幾乎一樣有用婚被,但是有些情況下對于代碼相對過于嚴苛狡忙。一個很常見的例子是,-Wextra中包含了-Wsign-compare址芯, 這個警告標識會開啟比較時候?qū)igned和unsigned的類型檢查灾茁,當比較符兩邊一邊是signed一邊是unsigned時,產(chǎn)生警告谷炸。其實很多 代碼并沒有特別在意這樣的比較北专,而且絕大多數(shù)時候,比較signed和unsigned也是沒有太大問題的(當然不排除會有致命錯誤出現(xiàn)的情況)旬陡。需要注意拓颓,-Wextra和-Wall是相互獨立的兩個警告組,雖然里面打開的警告標識有個別是重復的描孟,但是兩組并沒有包含的關(guān)系驶睦。想要同時使用的話必須都加上

  • -Weverything 這個是真正的所有警告。但是一般開發(fā)者不會選擇使用這個標識匿醒,因為它包含了那些還正在開發(fā)中的可能尚存bug的警告提示场航。這個標識一般是編譯器開發(fā)者用來調(diào)試時使用的,如果你想在自己的項目里開啟的話青抛,警告一定會爆棚導致你想開始撞墻..

這里推薦-Wall和-Wextra旗闽,或者-Wextra,設(shè)置后運行程序警告數(shù)成倍的增長,看看其中哪些是真正的bug适室。

屏幕快照 2017-03-26 下午1.21.17.png

Clang和靜態(tài)分析(Static Analyzer)

靜態(tài)分析一般指的是使用工具來分析代碼并找出安全漏洞嫡意。這可能涉及識別一系列危險的API,或分析通過應(yīng)用程序的數(shù)據(jù)流捣辆,來標識潛在不安全的程序輸入蔬螟。

Xcode中提供了一個UI界面工具。用戶可以使用該工具很直觀的完成邏輯追蹤汽畴、代碼漏洞以及通用API誤用等分析操作旧巾。但有一些重要特性,Xcode默認是禁止忍些。其中值得關(guān)注的特性有:對C語言庫函數(shù)等經(jīng)典威脅的檢查鲁猩,比如針對strcpy和strcat的檢查就是默認關(guān)閉的。你可以在項目或Target設(shè)置中開啟這些特性:

屏幕快照 2017-03-26 下午1.33.09.png

在Xcode8中罢坝,靜態(tài)分析能夠檢測出三種新的錯誤, 它們分別是Localizability廓握、Instance Cleanup、Nullability嘁酿。

  • Localizability 其實說的是靜態(tài)分析能夠檢測出本地化信息缺失的問題隙券,目前能夠檢測出來兩種類型的錯誤块差,一種是沒有使用 NSLocalizeString這樣的API渐夸,而直接給控件設(shè)置Sting的情況,一種是使用了相應(yīng)的API虫溜,但在comment信息里面賦值為nil游桩。默認是不開啟的牲迫,在BuildSting中作如下設(shè)置:
屏幕快照 2017-03-26 下午1.46.12.png
  • Instance Cleanup 在MRC的代碼中,尤其在dealloc中众弓,我們不應(yīng)該對assign類型的屬性進行release操作恩溅,應(yīng)該對retain或者 copy類型的屬性進行release操作隔箍,如果不這樣操作的話谓娃,會引發(fā)一些不必要的麻煩

  • Nullability 在2015年的WWDC大會上,Objective-C引入的一個新特性就叫做Nullability蜒滩,用于表明一個東西到底可以為nil還是不可以為nil滨达,這和Swift里的option類型很相似。

Sanitizer和動態(tài)分析

  • Sanitizer是一個用于優(yōu)化的工具俯艰。

在edit scheme->Diagnostics->Runtime Sanitizer中勾選相應(yīng)的Sanitizer選項捡遍。

屏幕快照 2017-03-26 下午6.44.40.png

勾選了相應(yīng)的選項并不代表你就能使用 Sanitizer 來Check代碼了, 你還必須重新run一下代碼,為什么呢?

這就必須說說整個代碼 build flow 了. 如下圖所示, 通過勾選了對應(yīng)的選項, Xcode 會向 clang 傳遞一個特定的參數(shù), 然后生成一個獨特的 binary, 然后這個 binary 會和 Thread Sanitizer 或者 Address Sanitizer 的 dylib 鏈接在一起. 這樣 Sanitizer 就實現(xiàn)了它想要達到的功能.

406302-b3a58fd1cf107857.jpg

Address Sanitizer(ASan)是一個類似Valgrind的動態(tài)分析工具竹握,ASan可以檢測出堆画株、棧溢出和釋放后又被使用的bug,還能找到關(guān)鍵的安全漏洞。ASan會對性能產(chǎn)生一些影響(程序執(zhí)行速度會慢一些)谓传,因此不要在發(fā)行版本中啟用這個選項蜈项,但是在測試、質(zhì)量保證檢測或是缺陷測試階段续挟,使用這一特性帶來便利吧紧卒。ASan能檢查以下類型的錯誤:

  • Use after free
  • Heap bu?er over?ow
  • Stack bu?er over?ow
  • Global variable over?ow
  • Over?ows in C++ containers
  • Use after return
- (void)viewDidLoad {
    [super viewDidLoad];
    
    char *buffer = malloc(10);
    buffer[10] = 'A';
    free(buffer);
}

運行上面的代碼,在開啟ASan時诗祸,程序會崩潰在“buffer[10] = 'A';”這一行跑芳,并顯示相應(yīng)的崩潰類型。在不開啟ASan時直颅,不添加任何斷點時博个,程序會崩潰在main函數(shù)里;添加任何斷點后功偿,程序不會崩潰坡倔。

問題很明顯,這是一個數(shù)組越界脖含,開啟ASan后會直接定位到問題發(fā)生的地方罪塔,不開啟的話,阿彌陀佛了养葵。

  • Thread Sanitizer (TSan)是Xcode8的新特性征堪,檢測線程方面的問題。

讓我們想想自己在調(diào)試線程方面的 bug 時, 有哪些令人記憶深刻的東西:

  • 線程方面的 bug 對時間很敏感, 這就導致很多線程的 bug 極難復現(xiàn), 復現(xiàn)都成問題, 還怎么改 bug
  • 由于線程的抽象概念導致在 debug 時候也比一般的 debug 更費勁兒, 這時候總覺自己腦子不夠使
  • 有時候, 由于線程引起的 crash 或者 error ,讓我們根本意識不到這其實是線程出了問題

在Address Sanitizer下面勾選Thread Sanitizer关拒。至于 Thread Sanitizer下面的那個Pause on Issues的選項就是說佃蚜,如果你想一個一個看runtime issue就勾選它,如果你不想這樣着绊,就不要勾選它谐算, 具體是個神馬感覺,你自己試試嘍归露。

如果你喜歡使用 Comman-Line ,那么請記住下面的代碼

//Compile and Link with TSan
$ clang -fsanitize=thread source.c -o executable
$ swift -sanitize=thread source.swift -o executable
$ xcodebuild -enableThreadSanitizer YES

//Stop after the first error
$ TSAN_OPTIONS=halt_on_error=1 ./executable

TSan現(xiàn)在只支持64位macOS洲脂,以及64位的iOS和tvOS的模擬器,并不支持真機調(diào)試和watchOS剧包。

那么TSan作為一個能夠檢查線程錯誤的工具, 它能檢查以下類型的錯誤:

  • Use of uninitialized mutexes(使用未初始化的互斥器)
  • Thread leaks (missing phread_johin)(線程泄漏)
  • Unsafe calls in signal handlers (ex:malloc)()
  • Unlock from wrong thread(從錯誤的線程解鎖)
  • Data race(數(shù)據(jù)沖突)

那么我們拿下面的這段代碼來舉例:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self resetStatue];
    pthread_mutex_init(&(_mutex), NULL);
}

- (void)resetStatue{
    [self acquireLock];
    self.dataArray = nil;
    [self releaseLock];
}

- (void)acquireLock{
    pthread_mutex_lock(&_mutex);
}

- (void)releaseLock{
    pthread_mutex_unlock(&_mutex);
}

這里我們?yōu)榉乐苟鄠€線程去訪問同一個dataArray屬性恐锦,在resetStatue方法中使用了互斥鎖,但是resetStatue的調(diào)用是在互斥鎖初始化(pthread_mutex_init(&(_mutex), NULL))之前疆液,這樣的調(diào)用順序是錯誤的一铅,在不開啟TSan時,程序不會發(fā)生崩潰堕油。開啟Tasn后潘飘,效果如下:

屏幕快照 2017-03-26 下午7.33.48.png

左邊runtime issue中明確的告訴了我們錯誤的類型(Use of uninitialized mutexes)肮之,而且把線程中的歷史信息都記錄了下來以便我們分析并解決這個問題。

在開發(fā)中我們還會用到Reveal卜录、Charles局骤、Instruments的Leaks、Time Profiler等工具暴凑,掌握這些后會讓你在開發(fā)中發(fā)現(xiàn)問題峦甩、解決問題更加容易,提高生產(chǎn)力现喳。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凯傲,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嗦篱,更是在濱河造成了極大的恐慌冰单,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灸促,死亡現(xiàn)場離奇詭異诫欠,居然都是意外死亡,警方通過查閱死者的電腦和手機浴栽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門荒叼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人典鸡,你說我怎么就攤上這事被廓。” “怎么了萝玷?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵嫁乘,是天一觀的道長。 經(jīng)常有香客問我球碉,道長蜓斧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任睁冬,我火速辦了婚禮挎春,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痴突。我一直安慰自己搂蜓,他們只是感情好狼荞,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布辽装。 她就那樣靜靜地躺著,像睡著了一般相味。 火紅的嫁衣襯著肌膚如雪拾积。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音拓巧,去河邊找鬼斯碌。 笑死,一個胖子當著我的面吹牛肛度,可吹牛的內(nèi)容都是我干的傻唾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼承耿,長吁一口氣:“原來是場噩夢啊……” “哼冠骄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起加袋,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤凛辣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后职烧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扁誓,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年蚀之,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝗敢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡足删,死狀恐怖前普,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情壹堰,我是刑警寧澤拭卿,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站贱纠,受9級特大地震影響峻厚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谆焊,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一惠桃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辖试,春花似錦辜王、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莲兢,卻和暖如春汹来,著一層夾襖步出監(jiān)牢的瞬間续膳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工收班, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坟岔,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓摔桦,卻偏偏與公主長得像社付,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邻耕,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容