關于iOS里的警告
iOS調(diào)試
前言
一個好的程序猿,會重視他寫的每一行代碼,看到警告會去思考為什么,會去盡量的消除警告,消除警告是代碼潔癖必不可少的一項。所以對于iOS開發(fā)者來說了解警告的類型,并開啟必要的警告是必須的。下面是Build Setting里關于warning的配置選項。
Apple LLVM 8.0 - Warning Policies
這是關于所有warning的策略,分為以下三個點:
禁止所有的Warnings
Inhibit All Warnings表示是否禁止所有的Warnings,默認為NO。如果設置為YES,那你就不會得到任何警告提示了。
迂腐的Warnings
Pedantic Warnings這個主要跟C和C++的標準有關,Pedantic意思是迂腐的,也就是說那些沒有嚴格按照ISO C和ISO C++標準的代碼是否顯示。默認為NO,也就是不提示。
將警告等于錯誤
Treat Warnings as Errors,一種很常見的做法和代碼潔癖是將警告標識為錯誤,從而中斷編譯過程。這讓開發(fā)者不得不去修復這些警告,從而保持代碼干凈整潔。這個選項默認是NO,設置為YES,就會將警告等于錯誤。有時候我們在開發(fā)時不想被一些簡單的warning給打斷,那么可以先設置Debug為NO,Release為YES,在build release時就可以發(fā)現(xiàn)這些warning了。
我們也可以在Other C Flags里加入-Werror標識將警告等于錯誤。
如果要將某一類警告等于錯誤可以這樣寫-Werror=...。示例如下:

設置
-Werror=unused-function之后表示只有unused-function警告等于錯誤。
也可以在
-Werror被激活時使用-Wno-error=...來使某些警告不成為錯誤。示例如下:

設置
-Werror和-Wno-error=unused-function之后表示除unused-function之外的所有警告都等于錯誤。
Build Setting里的警告選項
Xcode的工程模板已經(jīng)為我們設置開啟了一些默認和常用的警告提示,但是這些警告有時候是不夠的,你需要開啟更多的警告類型來找到你代碼中不合理的地方。
主要分為以下幾大塊:
Apple LLVM 8.0 - Warning - All languages、
Apple LLVM 8.0 - Warning - C++、
Apple LLVM 8.0 - Warning - Objective C、
Apple LLVM 8.0 - Warning - Objective C and ARC。
在上面這些大塊下面都有對應warning的配置選項。如下圖是跟All languages相關的一些warning,我們能看到之前例子里的兩種類型的warning設置為YES,表示這兩種類型的warning是提示的。

Other C Flags
我們上面有提到在Other C Flags中加入-Werror、-Wno-error=...、-Werror=...,來實現(xiàn)類似于Treat Warnings as Errors選項的效果及更強大的擴展。
其實我們也可以在Other C Flags加入特別的標識來達到Build Setting里設置對應警告選項BOOL值的效果。
Other C Flags里設置的優(yōu)先級是大于某一個具體配置的。如在Apple LLVM 8.0 - Warning - All languages中的選項Unused Variable設置為YES,那么就表示這種類型的warning是會提示的。但是我在Other C Flags中加入-Wno-unused-variable,表示這種類型的warning是不提示的。
那么最后以Other C Flags中的設置為準,也就是不會提示這種類型的warning。
Other C Flags中具有以下幾種標記類型:
將警告等于錯誤相關
這部分上面已經(jīng)提到過,包括-Werror、-Wno-error=...、-Werror=...。
打開或關閉某些警告
-W...開啟某些警告,如-Wunused-variable。-Wno-...關閉某些警告,如-Wno-unused-variable。
打開某一警告組
-Wall 并不是所有警告。這一個警告組開啟的是編譯器開發(fā)者對于“你所寫的代碼中有問題”這一命題有著很高的自信的那些警告。要是在這一組設定下你的代碼出現(xiàn)了警告,那基本上就是你的代碼真的存在嚴重問題了。但是同時,并不是說打開Wall就萬事大吉了,因為Wall所針對的僅僅只是經(jīng)典代碼庫中的為數(shù)不多的問題,因此有一些致命的警告并不能被其捕捉到。但是不論如何,因為Wall的警告提供的都是可信度和優(yōu)先級很高的警告,所以為所有項目(至少是所有新項目)打開這組警告,應該成為一種良好的習慣。
-Wextra 如其所名,
-Wextra組提供“額外的”警告。這個組和-Wall組幾乎一樣有用,但是有些情況下對于代碼相對過于嚴苛。一個很常見的例子是,-Wextra中包含了-Wsign-compare,這個警告標識會開啟比較時候?qū)igned和unsigned的類型檢查,當比較符兩邊一邊是signed一邊是unsigned時,產(chǎn)生警告。其實很多代碼并沒有特別在意這樣的比較,而且絕大多數(shù)時候,比較signed和unsigned也是沒有太大問題的(當然不排除會有致命錯誤出現(xiàn)的情況)。需要注意,-Wextra和-Wall是相互獨立的兩個警告組,雖然里面打開的警告標識有個別是重復的,但是兩組并沒有包含的關系。想要同時使用的話必須在Other C Flags中都加上。-Weverything 這個是真正的所有警告。但是一般開發(fā)者不會選擇使用這個標識,因為它包含了那些還正在開發(fā)中的可能尚存bug的警告提示。這個標識一般是編譯器開發(fā)者用來調(diào)試時使用的,如果你想在自己的項目里開啟的話,警告一定會爆棚導致你想開始撞墻。
查看警告類型的標識名
如果知道對應類型的warning的標識名是什么?
可以先查看左側(cè)的warning提示,如下圖中就是unused-variable和unused-function兩種警告的標識。

或者查看GCC的手冊,里面會列出很多標識,基本上跟warning提示對比下應該就能找出來了。
控制警告,局部加入或關閉
Clang提供了我們自己加入警告或者暫時關閉警告的辦法。
加入警告
強制加入一個警告:
<pre class="prettyprint linenums prettyprinted" data-anchor-id="8ltr" style="padding: 9.5px; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 14px; color: rgb(51, 51, 51); border-radius: 4px; display: block; margin: 0px 0px 20px; line-height: 20px; word-break: break-all; overflow-wrap: break-word; white-space: pre-wrap; background: none 0px 0px repeat scroll rgba(102, 128, 153, 0.05); border: 0px solid rgba(0, 0, 0, 0.15); box-shadow: rgba(255, 255, 255, 0.1) 0px 1px 2px inset, rgba(102, 128, 153, 0.05) 45px 0px 0px inset, rgba(102, 128, 153, 0.05) 0px 1px 0px;">
//Generate a warning#pragma message "Warning 1"//Another way to generate a warning#warning "Warning 2"
</pre>
兩種強制警告的方法在視覺效果上結果是一樣的,但是警告類型略有不同,一個是-W#pragma-messages,另一個是-W#warnings。對于第二種寫法,把warning換成error,可以強制使編譯失敗。比如在發(fā)布一些需要API Key之類的類庫時,可以使用這個方法來提示別的開發(fā)者別忘了輸入必要的信息。
<pre class="prettyprint linenums prettyprinted" data-anchor-id="egkd" style="padding: 9.5px; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 14px; color: rgb(51, 51, 51); border-radius: 4px; display: block; margin: 0px 0px 20px; line-height: 20px; word-break: break-all; overflow-wrap: break-word; white-space: pre-wrap; background: none 0px 0px repeat scroll rgba(102, 128, 153, 0.05); border: 0px solid rgba(0, 0, 0, 0.15); box-shadow: rgba(255, 255, 255, 0.1) 0px 1px 2px inset, rgba(102, 128, 153, 0.05) 45px 0px 0px inset, rgba(102, 128, 153, 0.05) 0px 1px 0px;">
//Generate an error to fail the build.#error "Something wrong"
</pre>
關閉警告
全局關閉
在build setting里找到對應的警告選項設置為NO即可?;蛘咴?code>build setting中的Other C Flags里加入-Wno-...標識。相應文件關閉
在Build Phases的Compile Source相應的文件中的Compiler Flags加入對應的編譯標識即可,如-Wno-unused-variable。優(yōu)先級如下:
Build Phases的Compile Source>Build Setting的Other C Flags>Build Setting中的某一中具體warning的開關
相對文件打開警告也類似。-
在某幾行關閉某個警告
<pre class="prettyprint linenums prettyprinted" style="padding: 9.5px; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 14px; color: rgb(51, 51, 51); border-radius: 4px; display: block; margin: 0px 0px 20px; line-height: 20px; word-break: break-all; overflow-wrap: break-word; white-space: pre-wrap; background: none 0px 0px repeat scroll rgba(102, 128, 153, 0.05); border: 0px solid rgba(0, 0, 0, 0.15); box-shadow: rgba(255, 255, 255, 0.1) 0px 1px 2px inset, rgba(102, 128, 153, 0.05) 45px 0px 0px inset, rgba(102, 128, 153, 0.05) 0px 1px 0px;">
#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wunused-variable"int a;#pragma clang diagnostic pop
</pre>
這樣如果之后a未被使用,也不會出現(xiàn)
unused-variable類型的警告了。
警告類型列表
這里我整理了一篇專門收集警告:iOS警告類型,以供參考。
相關問題
pod里的警告沒有提示
需要在Edit Scheme->Build里加入對應pod的target,才能顯示那個pod里的警告。
警告開啟建議
個人喜好(代碼潔癖)不同,會有不同的需求。我的建議是對于所有項目,特別是新開的項目,首先開啟-Wall和-Wextra,然后在此基礎上構建項目并且避免一切警告。如果在開發(fā)過程中遇到了某些確實無法解決或者確信自己的做法是正確的話(其實這種情況,你的做法一般即使不是錯誤的,也會是不那么正確的),可以有選擇性地關閉某些警告。一般來說,關閉的警告項目不應該超過一只手能數(shù)出來的數(shù)字,否則一定哪兒出問題了.
關閉的warning需要列出文檔以供開發(fā)人員參考,知道哪些warning關閉了。包括全局關閉、相應文件關閉、在某幾行關閉某個警告等。
參考
談談Objective-C的警告
清除Masonry中的警告
轉(zhuǎn)載自:https://www.zybuluo.com/qidiandasheng/note/663838