1. 程式人生 > >Xcode執行Analyze靜態分析

Xcode執行Analyze靜態分析

  • 使用Xcode自帶的靜態分析工具 Product->Analyze(快捷鍵command+shift+B)可以找出程式碼潛在錯誤,如記憶體洩露,未使用函式和變數等

所謂靜態記憶體分析, 是指在程式沒執行的時候, 通過工具對程式碼直接進行分析
根據程式碼的上下文的語法結構, 讓編譯器分析記憶體情況, 檢查是否有記憶體洩露

Analyze主要分析以下四種問題:

  • 1、邏輯錯誤:訪問空指標或未初始化的變數等;
  • 2、記憶體管理錯誤:如記憶體洩漏等; 比如ARC下,記憶體管理不包括core foundation
  • 3、宣告錯誤:從未使用過的變數;
  • 4、Api呼叫錯誤:未包含使用的庫和框架。

    缺點: 靜態記憶體分析由於是編譯器根據程式碼進行的判斷, 做出的判斷不一定會準確, 因此如果遇到提示, 應該去結合程式碼上文檢查一下

// 面向使用者的文字應該使用本地化的字串巨集
1.user-facing text should use localized string macro

此為程式碼中配置了本地化,面向使用者的應該用字串巨集,而我們直接賦值為漢字,因此,此提示可以忽略.

2.instance variable used while 'self' is not set to the result of '[(super or self) init...]

// 此方法提示錯誤
- (instancetype)initWithType:(FTFFavorateType)type
{
    if (self == [super
init]) { _type = type; } return self; }

修改為如下

- (instancetype)initWithType:(FTFFavorateType)type
{
    if (self = [super init]) {
        _type = type;
    }
    return self;
}
// 在初始化過程中儲存的“持續時間值”的值永遠不會被讀取
3.Value stored to ‘durationValue’ during its initialization is never read

// 此段程式碼提示錯誤
NSMutableArray *datesArray = [[NSMutableArray alloc] init]; datesArray = [_onDemandDictionary objectForKey:key];

這是因為[NSMutableArray alloc] init]初始化分配了記憶體,而判斷語句裡面[_onDemandDictionary objectForKey:key]方法也相當於初始化分配了記憶體,就是把初始化的一個新的可變陣列賦值給之前已經初始化過的可變陣列,看似沒什麼大問題,其實存在一個數據源卻申請了兩塊記憶體的問題,已經造成了記憶體洩露。

修改為如下

NSMutableArray *datesArray = nil;
datesArray = [_onDemandDictionary objectForKey:key];

Analyze已經分析出imageRef物件有記憶體洩漏,這種情況在編譯時是無法發現的。
//擷取部分影象

+(UIImage*)getSubImage:(unsigned long)ulUserHeader
{
    UIImage * sourceImage = [UIImage imageNamed:@"header.png"];
    CGFloat height = sourceImage.size.height;
    CGRect rect = CGRectMake(0 + ulUserHeader*height, 0, height, height);

    CGImageRef imageRef = CGImageCreateWithImageInRect([sourceImage CGImage], rect);
    UIImage* smallImage = [UIImage imageWithCGImage:imageRef];
    //CGImageRelease(imageRef);

    return smallImage;
}

Analyze邏輯錯誤監測:


test.png

這種情況在codereview時也較難發現,可以藉助Analyze。
如上程式碼,當Tag不等於1、2和3的時候,就會出現很問題了。
Analyze還給出了箭頭提示:len is a garbage value。建議在宣告變數時,同時進行初始化。