【iOS】iOS警告收錄與消除方法
原文轉自:董鉑然 原文較老,對其中的代碼做了部分修改
前言:現在你維護的項目有多少警告?看著幾百條警告覺得心里煩么?你真的覺得警告又不是錯誤可以完全不管么? 如果你也被這些問題困惑,可以和我一起進行下面的操作。其實大部分的警告都是很好改的,把自己整個項目的警告擼一遍應該也就耗費半小時的時間,一次麻煩帶來之后的清凈這樣不好么?
本文分為三個部分:
- 簡單粗暴的消除警告。
- 詳細科學的消除警告。(包括警告收錄)
- 添加警告。
一、簡單粗暴的消除警告
警告如果是自己項目中的還好直接改了,如果是第三方庫,你改了之后,pod下作者更新一下又白改了,所以可以用這種簡單粗暴的方法:直接讓第三方庫的警告不顯示
就是在podfile文件里面加上一行指令 。
inhibit_all_warnings!
如果某警告實在無法消除,但是又不想讓他顯示,可以加入預編譯指令
比如我已經知道某行會報上面警告了,我就用這個宏把這幾行包住,就不會報引號中-Wunused-variable的警告了
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wunused-variable"
//這里是會報警告的代碼
#pragma clang diagnostic pop
這個-Wunused-variable代表的意思就是有的東西你實例化了但是沒有使用(同上面第幾條)。 但是如何得到一個警告的標示符?
如圖選擇一個警告,點擊右鍵,reveal in log 就能看到右邊有個方括號[]里面的東西就是 這個警告對應的標示符
如果希望整個項目中都忽略 某種很無聊的警告,就在項目中Build Setting里加上這個標示符,可以連著加的。
如果不想整個項目都忽略,只想個別文件忽略,那就找到個別文件加上此指令,這個操作應該使用率不高(一般都是全項目忽略),就不上圖了。去Build Phases 里面的 Compile Sources里面改。
二、詳細科學的消除警告
其實筆者本意是想把一些第一眼看不懂比較坑的警告收錄進來,但是后來發現那基本沒幾個需要些寫了,所以就采用了全收錄的方法,遇到的就記錄下以后也會不斷更新。
可以直接按command+F 在本頁面搜索警告
-
Unused variable 'replyURL'
沒有使用
-
Cannot find protocol definition for 'TencentSessionDelegate'
這種明明都能運行還說我沒有定義的警告,是因為你這個協議雖然定義了,但是你這個協議可能還遵守了XX協議,然后這個XX協議沒有定義導致會報這種警告,所以遇到這種警告要往“父協議”找。 舉個栗子,上面這行就是騰訊授權的庫里面報的警告,
@protocol TencentSessionDelegate<NSObject, TencentLoginDelegate, TencentApiInterfaceDelegate, TencentWebViewDelegate>
此協議遵守了TencentApiInterfaceDelegate協議,在TencentOAuth.h類中#import "TencentApiInterface.h" 警告可破
-
Null passed to a callee that requires a non-null argument
這個警告比較新,是xcode6.3開始 為了讓OC也能有swift的?和!的功能,你在聲明一個屬性的時候加上 __nullable(?可以為空)與__nonnull(!不能為空) 如果放在@property里面的話不用寫下劃線
@property (nonatomic, copy, nonnull) NSString * tickets;
@property (nonatomic, copy) NSString * __nonnull tickets;
或者用宏NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END 包住多個屬性全部具備nonnull,然后僅對需要nullable的改下就行,有點類似于f-no-objc-arc那種先整體給個路線在單獨改個別文件的思想。 此警告就是某屬性說好的不能為空,你又在某地方寫了XX = nil 所以沖突了。
-
Auto property synthesis will not synthesize property 'privateCacheDirectory'; it will be implemented by its superclass, use @dynamic to acknowledge intention
他說你的父類實現了setget方法,但是如果你什么都不寫,就會系統自動生成出最一般的setget方法,請用@dynamic 來承認父類實現的這個getset方法。
-
Unsupported Configuration: Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:.
一般是storyboard報的警告,簡而言之就是你有的頁面沒有和箭頭所指的控制器連起來,導致最終改頁面可能無法顯示。
-
Deprecated: Push segues are deprecated in iOS 8.0 and later
iOS8之后呢,不要再用push拖線了,統一用show,他會自己根據你是否有導航欄來判斷走push還是走modal
-
Unsupported Configuration: Plain Style unsupported in a Navigation Item
導航欄的item 不支持用plain ,那就用Bordered唄。
-
The launch image set "LaunchImage" has 2 unassigned images.
The app icon set "AppIcon" has 2 unassigned images.
幾張圖標還是啟動圖找不到自己的位置,可能是一次導入了全部尺寸圖片,但是右邊的設置只勾了iOS8的 那iOS7尺寸的圖標就會報此警告。刪掉,或者對照右邊匹配。
-
'sizeWithFont:constrainedToSize:lineBreakMode:' is deprecated: first deprecated in iOS 7.0 - Use -boundingRectWithSize:options:attributes:context:
方法廢除,舊的方法sizeWithFontToSize在iOS7后就廢除了取而代之是boundingRectWithSize方法
-
Undeclared selector 'historyAction'
使用未聲明的方法,一般出現在@selector() 括號里寫了個不存在的方法或方法名寫錯了。
-
PerformSelector may cause a leak because its selector is unknown
這個和上面類似就是直接把上面那個@SEL拿來用會報這個警告
-
'strongify' macro redefined
這個宏聲明重復,刪一個吧
-
'UITextAttributeFont' is deprecated: first deprecated in iOS 7.0 - Use NSFontAttributeName
'UITextAttributeTextColor' is deprecated: first deprecated in iOS 7.0 - Use NSForegroundColorAttributeName
'UITextAttributeTextShadowColor' is deprecated: first deprecated in iOS 7.0 - Use NSShadowAttributeName with an NSShadow instance as the value
方法廢除,一般一起出現
-
Code will never be executed
這代碼永遠也輪不到他執行,估計是有幾行代碼寫在了return之后
-
Assigning to 'id
' from incompatible type 'SXTabViewController *const __strong' 一般出現在xxx.delegate = self ,應該在上面遵守協議
-
Format specifies type 'unsigned long' but the argument has type 'unsigned int'
這個警告一般會出現在NSStringWithFormat里面 前面%d %lu 什么的和后面填進去的參數不匹配就報了警告
-
Values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead
類似于上面,也是format里面前后寫的不匹配
-
Method 'dealWithURL:andTitle:andKeyword:' in protocol 'SXPostAdDelegate' not implemented
經典警告,遵守了協議,但是沒有實現協議方法。 也可能你實現了只是又加了個參數或是你寫的方法和協議方法名字有點輕微不同
-
Using integer absolute value function 'abs' when argument is of floating point type
這個可以自動修正,就是說abs適用于整數絕對值,要是float取絕對值要用fabsf
-
Attribute Unavailable: Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
有的方法你用的太落后了,也有的方法你用的太超前了。 說這個最大寬度在iOS8之前的系統是要坑的
-
Too many personality routines for compact unwind to encode
你可以在otherlink 中加入 -Wl,-no_compact_unwind 去掉該警告,根據蘋果的解釋,這個是由于某些地方 c/c++/oc/oc++混用會造成編譯警告。一般沒有什么傷害。
-
Property 'ssid' requires method 'ssid' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation
說這個ssid必須要定義個這個屬性的getter方法,如果警告是setSsid就是setter方法, 用@synthesize和@dynamic 都行,一個是讓編譯器生成getter和setter,一個是自己生成,如果你有模型分發或kvc之類的,選@dynamic就行
-
Unknown escape sequence ')'
未知的轉義序列。 一般有個斜杠再加個東西他都會以為是轉義字符,一看\)不認識就報警告了,一般正則表達式容易報這種警告
-
Property 'LoginPort' not found on object of type 'LoginLvsTestTask *'; did you mean to access property loginPort?
這種可以點擊自動修復,是典型的大小寫寫錯了,他提醒了一下。
-
Variable 'type' is used uninitialized whenever switch default is taken
這是出現在switch語句中的警告, 一般可能是switch外面定義了個type但是并沒有初始化(初始化操作都寫在switch的各個分支里),然后在最后return type。 但是switch的有個分支沒有對type初始化,他說如果你來到這個分支的話,那還沒初始化就要被return。
三、添加警告
1.首先最常用的就是 普通警告,這也沒什么好說的了
#warning TODO
2.如果是自己寫的文件或第三方庫,有了新的接口,然后提示舊的接口廢除的話需要在方法后加上宏NS_DEPRECATED_IOS和范圍
- (void)addTapAction:(SEL)tapAction target:(id)target NS_DEPRECATED_IOS(2_0, 4_0);
3.如果需要在此方法后加上帶信息的警告則需要這么寫
- (void)addTapAction:(SEL)tapAction target:(id)target __attribute__((deprecated("這個接口已廢棄,建議使用...代替")));
//系統提供了宏可以簡單使用
- (void)addTapAction:(SEL)tapAction target:(id)target DEPRECATED_MSG_ATTRIBUTE("這個接口已廢棄,建議使用...代替");
顯示的效果像這樣:

內容的補充:
//精確忽略指定代碼塊的警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "警告名稱"
// 被夾在這中間的代碼針對于此警告都會忽視不顯示出來
//常見警告的名稱
//1.聲明變量未使用 "-Wunused-variable"
//2.方法定義未實現 "-Wincomplete-implementation"
//3.未聲明的選擇器 "-Wundeclared-selector"
//4.參數格式不匹配 "-Wformat"
//5.廢棄掉的方法 "-Wdeprecated-declarations"
//6.不會執行的代碼 "-Wunreachable-code"
//7.忽略在arc 環境下performSelector產生的 leaks 的警告 "-Warc-performSelector-leaks"
//8.忽略類別方法覆蓋的警告 "-Wobjc-protocol-method-implementation"(修復開源庫bug,覆蓋開源庫方法時會用到)
#pragma clang diagnostic pop
大范圍忽略指定警告
不推薦,警告放開有利于及時查找問題,大范圍忽略警告容易導致一些隱匿性的錯誤難以定位
可以在pch等具有大范圍作用域的頭文件中包含:
#pragma clang diagnostic ignored "警告名稱"
如果剔除了push與pop 則后面所有的代碼都具有強制消除警告作用



浙公網安備 33010602011771號