1. 程式人生 > >iOS記憶體檢測工具Analyze的使用

iOS記憶體檢測工具Analyze的使用

XCode的Analyze可以分析到專案哪裡有記憶體洩露.

  方法:xcode----product-----Analyze(快捷鍵:Shift + Cmd + B)
iOS的分析工具可以發現編譯中的warning,記憶體洩漏隱患,甚至還可以檢查出logic上的問題;所以在自測階段一定要解決Analyze發現的問題,可以避免出現嚴重的bug;
常見問題
1.記憶體洩漏隱患提示:Potential Leak of an object allocated on line …
2.資料賦值隱患提示:The left operand of …… is a garbage value;
3.物件引用隱患提示:Reference-Counted object is
used after it is released; 以上提示均比較嚴重,可能會引起嚴重問題,需要開發者密切關注!

1、檢測記憶體洩漏時出現洩漏提示:User-facing text should use localized string macro。
// 面向使用者的文字應該使用本地化的字串巨集
.user-facingtextshould use localizedstringmacro。
這裡寫圖片描述
此為程式碼中配置了本地化,面向使用者的應該用字串巨集,而我們直接賦值為漢字,因此,此提示可以忽略.
解決辦法:
這裡寫圖片描述
2、重寫UIViewController的生命週期方法沒有呼叫父類的方法

 The 'viewWillDisappear:' instance method in UIViewController subclass 'TestDetailsViewController' is missing a [super viewWillDisappear:] call

-(void)viewWillDisappear:(BOOL)animated
{
}
解決方案:
-(void)viewWillDisappear:(BOOL)animated
{    
    [super viewWillDisappear:animated];
}

3、初始化的變數並沒有被使用

提示示例:value stored to ‘YourVariable’ is never read
解決辦法:
如果無用的話,刪除或者註釋即可!
如果有用的話,檢查為何沒有被使用!

4、變數多次初始化,其中的某些初始化的變數並沒有使用過

提示示例:value stored to ‘YourVariable’during its initialization is never read
錯誤程式碼示例:
NSMutableArray *tempMutArr = [NSMutableArray arrayWithCapacity:0];
    if ([self.clickedButtonTpye isEqualToString:KClickedButtonTypeLast]) {
        tempMutArr = self.lastDataSourceArr;
    }else{
        tempMutArr = self.hotDataSourceArr;
    }

仔細看了程式碼後才發現程式碼存在一個細節上的問題,也正是這個細節導致的記憶體洩漏。
在專案裡我的self.lastDataSourceArrself.hotDataSourceArr都是已經初始化過的可變陣列,
但是在if裡我又重新初始化了一個新的可變陣列,並且把之前已經初始化過的可變陣列賦值給了它,
這就是內訓洩漏的問題所在,看似程式碼沒有大的問題,但是其實已經造成了記憶體洩漏
原因是:因為self.lastDataSourceArrself.hotDataSourceArr是已經建立並且分配過記憶體的可變陣列了,但是我把這些陣列又賦值給了重新建立並分配了記憶體的可變陣列tempMutArr,所以這樣就出現了一個數據源卻申
請了兩塊記憶體的情況,那麼就存在一塊記憶體空閒了,所以就存在了記憶體洩漏。

解決辦法:

無用的初始化直接去掉!
NSMutableArray *tempMutArr;
    if ([self.clickedButtonTpye isEqualToString:KClickedButtonTypeLast]) {
        tempMutArr = self.lastDataSourceArr;
    }else{
        tempMutArr = self.hotDataSourceArr;

這樣只做了一個可變陣列tempMutArr的宣告,不需要給它分配實際記憶體,就可以賦值了,
其實只是聲明瞭這樣一個物件,使其持有對原有資料物件的引用即可。

5、重新父類的初始化方法時沒有呼叫父類的初始化方法

錯誤程式碼示例:

-(instancetype)initWithFrame:(CGRect)frame{
if(self== [superinitWithFrame:frame]){
    [self setView];
}
returnself;
}

解決辦法:
先呼叫父類的初始化方法,再自定義處理

-(instancetype)initWithFrame:(CGRect)frame{
self = [superinitWithFrame:frame];
if (self) {
    [self setView];
}
returnself;
}

6、變數未初始化就使用了
錯誤資訊:The left expression of the compound assignment is an uninitialized value. The computed value will also be garbag
提示示例:The left operand of ‘+’ is a garbage value
錯誤示例;

   NSInteger ret;
    ret += 2;
    NSLog(@"%ld",ret);
解決方式:初始化資料。NSInteger ret = 1;

7、自定義的方法名和系統的方法名重名,且返回的型別不一樣:
The Objective-C class ‘LZBKeyBoardToolBar’, which is derived from class ‘UIResponder’, defines the instance method ‘becomeFirstResponder’ whose return type is ‘void’. A method with the same name (same selector) is also defined in class ‘UIResponder’and has a return type of ‘BOOL’. These two types are incompatible, and may result in undefined behavior for clients of these classes
自己定義的方法:
這裡寫圖片描述
系統的方法:
這裡寫圖片描述
解決方式:命名方式不要和系統方法重名,改一下自己定義方法的名字。
寫的都是我發現和整理的問題,歡迎大家來繼續補全。