前言
歷經(jīng)兩個月,我終于完成了第一個C端項目全民星跑,整個工程總共8萬行代碼(包含注釋行).作為強迫癥的我把這個項目整的一個警告都沒有,有人問我是不是因為我做了什么屏蔽工作,一鍵屏蔽什么的,其實這根本不存在的,其實我在開始架構(gòu)整個工程的時候,就開始注意警告的個數(shù)了,加上大部分的控件三方都是自己寫的,所以只要出現(xiàn)警告也是容易解決的,然后到項目的最后上線的時候,工程已經(jīng)沒有任何警告了.
有人會問,那么工程沒有警告到底有什么好處呢?我知道的只有一個好處,那就是在項目編譯的時候是非常的快,因為編譯警告也是需要時間的.(PS:此處的好處未經(jīng)過證實....)
屏蔽警告
因為項目中我很少用到其他的三方,大部分是我自己寫的,有用到的三方比如高德地圖也是最新版本的,所以我很少用到屏蔽警告,但是我在做老項目版本迭代時候用到過屏蔽警告,主要是因為如果我隨意篡改工程的話,可能會影響工程的功能,所以有些問題我只屏蔽了,還有的是一些三方的支持版本過低,或者是版本過時,做版本迭代的這個項目AFNetworking是2.5版的(早不知道過時多長時間了... ) 全部讓我手動改成AFNetworking3.0了,像這種比較常見的三方我還是建議不用屏蔽,直接手動升級到最新版本吧!
下面我就說幾個最常見的警告解決方案.
先說一個#pramark
預(yù)指令屏蔽警告方式,具體格式如下所示.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-相關(guān)命令"
// 你自己的代碼
#pragma clang diagnostic pop
忽略方法被棄用的警告(-Wdeprecated-declarations)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
UIAlertView *alerView = [[UIAlertView alloc]initWithTitle:@"忽略警告" message:@"忽略警告" delegate:self cancelButtonTitle:@"取消" otherButtonTitles: nil];
#pragma clang diagnostic pop
忽略不兼容指針類型的警告(-Wincompatible-pointer-types)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
//code這里插入相關(guān)的代碼
#pragma clang diagnostic pop
忽略循環(huán)引用的警告(-Warc-retain-cycles)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
self.completionBlock = ^ {
self.skScene = [SKScene sceneWithSize:self.videoNode.size];
};
#pragma clang diagnostic pop
忽略定義變量未使用的警告(-Wunused-variable)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
int i = 1;
#pragma clang diagnostic pop
忽略selector中使用了不存在的方法名的警告(-Wundeclared-selector)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
#pragma clang diagnostic pop
除了上面的警告之外,我們經(jīng)常會遇到一些三方最低支持版本比我們預(yù)設(shè)的項目版本要高很多,就會爆出如下的警告.
Object file(三方靜態(tài)庫中的源文件) was built for newer iOS version(三方版本) than being linked (工程版本)
這個警告屏蔽起來比較簡單,我們只需要在Build Settings ->Other Linker Flags中添加上一個-w字段即可.
還有就是我們會遇到如下警告.這表示是查詢 Library 的時候出現(xiàn)的異常召川。
"directory not found for option '-L/..."
我們只需要在Project -> targets -> Build Setting -> Library Search Paths中找到對應(yīng)的文件名刪除即可.
和上面的警告類似,我們在查詢 Framework 的時候也會出現(xiàn)異常。
"directory not found for option '-F/..."
我們只需要在Project -> targets -> Build Setting -> Framework Search Paths中找到對應(yīng)的文件名刪除即可.
那么,這種問題是如何造成的呢?可能就是因為哦們導(dǎo)入三方庫的時候,由于功能需求,我們不需要這個三方庫,我們移除的時候,在 Library 和 Framework 中并沒有移除對應(yīng)的路徑信息,所以就會爆出這樣的警告來.這樣的警告,我們注意下就可以完全消除了.
前任做的項目中含有友盟SDK(版本:4.2.1),經(jīng)常會爆出這樣的xib警告.
warning: Unsupported Configuration: This file is set to build for a version older than the deployment target. Functionality may be limited.
我們通過錯誤警告信息找到對應(yīng)的Xib文件,然后修改** Build for**屬性.
我們有時候在Debug模式下沒有警告但是在Release模式下出現(xiàn)了如下的警告.
warning:xxxx:No such file or directory
解決方案也是很簡單.我們只需要在Project -> targets -> Build Setting -> Debug Information Format把它的值改成DWARF即可.如下圖所示.
警告類型
performSelector may cause a leak because its selector is unknown
除了上圖的一些警告,我們自己給一個類寫Tager-Action的時候,會出現(xiàn)如下警告.
#import <UIKit/UIKit.h>
@interface TapView : UIView
//目標(biāo)
@property(weak,nonatomic)id target;
//行為
@property(assign,nonatomic)SEL action;
//自定義方法
-(void)addCustomtarget:(id)target andAction:(SEL)action;
@end
#import "TapView.h"
@implementation TapView
//自定義方法
-(void)addCustomtarget:(id)target andAction:(SEL)action{
_action = action;
_target = target;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//當(dāng)視圖點擊的時候,target去執(zhí)行action的方法并把自己傳過去.
//首先代理不能是空,而且代理(代理是對象!)的類中有方法并且能傳出過來.
if (nil != _target && [[_target class] instancesRespondToSelector:_action]) {
[_target performSelector:_action withObject:self];
}
}
@end
那么為什么在ARC環(huán)境下會造成這種情況呢?這是因為使用 [someController performSelector: NSSelectorFromString(@"someMethod")]; 時ARC并不知道該方法的返回值是什么,不知道該如何處理.所以就會爆這樣的錯誤,那么我們該如何解決呢?我們可以使用上面的預(yù)處理指令來屏蔽,不過最好的方法還是從根本上解決這個問題,我們可以使用函數(shù)指針的形勢來處理這個警告.如下所示.
if (nil != _target && [_target respondsToSelector:_action]) {
NSString *actionName = NSStringFromSelector(_action);
SEL selector = NSSelectorFromString(actionName);
IMP imp = [_target methodForSelector:selector];
void (*func)(id, SEL) = (void *)imp;
func(_target, selector);
}
警告類型
Pointer is missing a nullability type specifier.....
在iOS8.3的寫過一個輪播圖的三方,這個三方是沒有任何警告的,但是在這次使用的時候卻在初始化的時候,報了一個警告.如圖所示.
其實就是編譯器不知道我們這個是不是可為空的,第一個方法那就是我們一個個的修改,比較的繁瑣.解決完成之后如下圖所示.
第二種就是蘋果官方給我們提供的預(yù)處理指令,我們只需要把不可為空的屬性寫在其中即可.
NS_ASSUME_NONNULL_BEGIN
//不可為空的屬性
NS_ASSUME_NONNULL_END
示例如下如下所示.
總結(jié)
這邊文章到這里就結(jié)束了,但是我的分享之路還沒有結(jié)束,接下來,我會把全民星跑項目中的技術(shù)點來進行分析共享,也希望大家多多支持我做的騷應(yīng)用.