infer是Facebook?的?Infer?是一個靜態(tài)分析工具??梢苑治?Objective-C,?Java?或者?C?代碼,報告潛在的問題。
infer-項目地址為https://github.com/facebook/infer
infer-中文網(wǎng)站https://infer.liaohuqiu.net
安裝infer可以參考文檔https://github.com/facebook/infer/blob/master/INSTALL.md
infer的運(yùn)行原理,捕獲編譯命令,將文件翻譯成?Infer?內(nèi)部的中間語言。這種翻譯和編譯類似,Infer?從編譯過程獲取信息,并進(jìn)行翻譯。這就是我們調(diào)用Infer?時帶上一個編譯命令的原因了,比如:?infer -- clang -c file.c,?infer -- javac File.java。結(jié)果就是文件照常編譯,同時被?Infer?翻譯成中間語言,留作第二階段處理。特別注意的就是,如果沒有文件被編譯,那么也沒有任何文件會被分析。
infer?把中間文件存儲在結(jié)果文件夾中,一般來說,這個文件夾會在運(yùn)行?infer?的目錄下創(chuàng)建,命名是?infer-out/
—————
1.把infer.sh腳本放入需要掃描的工程根目錄。
2.跳轉(zhuǎn)到該工程目錄下,執(zhí)行該sh腳本
3.掃描的問題輸出在infer-out目錄下
由于項目代碼是在workspace文件中,可以使用xcodebuild –list?來查看workspace中的具體編譯模塊。
具體使用infer掃描的命令是infer -- xcodebuild -workspace "test.xcworkspace" -scheme "scheme"
在第二次使用infer掃描代碼時,需要進(jìn)行一次clean操作,具體的命令為xcodebuild clean -workspace ?"test.xcworkspace" -scheme"scheme"
掃描出的結(jié)果會在工程目錄下的infer-out文件中,其中具體的代碼會以csv,txt,json的格式分別存在對應(yīng)的文件中??梢怨┪覀兎治?/p>
過濾:由于大家App接入了一些第三方的庫,在分析代碼時,可以將一些第三方庫的問題進(jìn)行過濾,僅顯示我們自己的代碼問題。
可以過濾的目錄模塊路徑為,Pods,Weex,JSPatch,Masonry,,MBProgressHUD,?PublicProjects,?FXBlurView等
可以將代碼掃描出的bug列表利用file屬性進(jìn)行過濾。過濾腳本可以參考附件。
第一次,掃描主干代碼,總計掃出問題約1200個,過濾部分第三方庫后,還剩下約900個。
下面簡單描述一下通過infer掃描出來的問題:
1.??DIRECT_ATOMIC_PROPERTY_ACCESS。在代碼中使用了使用了一個atomic的成員變量,infer建議我們將atomic修改為nonatomic。由于OC中,屬性會被默認(rèn)設(shè)置為atomic屬性,我們需要顯示將屬性聲明為nonatomic。關(guān)于atomic與nonatomic的區(qū)別可以參見文章https://my.oschina.net/linxiaoxi1993/blog/381332
該警告占了大概800個。在代碼中主動設(shè)置成員變量的nonatomic屬性,即可去除警告
2.??ASSIGN_POINTER_WARNING
由于在mrc時代,沒有weak指針,所以一些view的屬性聲明是_、unsafe__unretain__的形式,在arc中,這個屬性被判斷為assign,需要將其修改為weak或者strong
3.??NULL_DEREFERENCE
空指針的情況。根據(jù)具體代碼的不同,出現(xiàn)空指針的情況也有所不同。
1.傳參為0的情況下。例如代碼中,在調(diào)用showAlertViewA()時,將tag傳參為0,infer檢測此處傳0,判斷為一個NULL空指針,所以爆出警告。這里可以理解為誤報,不會出現(xiàn)問題。
2.通過malloc,calloc,realloc等函數(shù)申請內(nèi)存,當(dāng)內(nèi)存不足時,有可能會在該函數(shù)中返回NULL,如果沒有做NULL的判斷,則警告
3.在創(chuàng)建NSArray或者NSDictionary時,傳入的參數(shù)有可能會nil。由于NSArray與NSDictionary不接受空指針,所以在對其addObject或者setObject:forKey:?時需要進(jìn)行判斷一下是否為nil。
4.??IVAR_NOT_NULL_CHECKED
在代碼中調(diào)用block,運(yùn)行代碼時,沒有做判空處理。即需要改動為,
if(block){block()}
5.??BAD_POINTER_COMPARISON
Implicitly checking whether NSNumber pointer is nil。沒有判斷一個NSNumber類型的對象是不是空?此處應(yīng)該是誤報。
6.??TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION
代碼中使用了cookie的value。可以理解為誤報
7.??PARAMETER_NOT_NULL_CHECKED
傳參時沒有判斷是否為null,加一次判斷就可以了
8.??STRONG_DELEGATE_WARNING
將一個delegate屬性設(shè)置為strong的類型。
9.??PREMATURE_NIL_TERMINATION_ARGUMENT
沒有判斷是否為空
10.REGISTERED_OBSERVER_BEING_DEALLOCATED
創(chuàng)建一個對象后,監(jiān)聽了某些通知,但是沒有在dealloc中釋放該通知。項目中出現(xiàn)這種問題的類,基本都是單例,不會被銷毀。
11.MEMORY_LEAK
內(nèi)存泄露。項目代碼全面啟動了ARC進(jìn)行內(nèi)存管理,在OC層沒有掃描出內(nèi)存泄露。目前掃描出的內(nèi)存泄露問題都是使用了malloc或者ralloc等c語言內(nèi)存申請函數(shù),在函數(shù)提前return前沒有及時free。