緣由
最近公司項目更新了幾個版本,主要是客戶端配合H5上一些活動和優化解決一些遺留下來的問題。review代碼的過程中,發現項目在模擬器里跑時內存使用很大,達到了130多兆,趁著剛發完新版有點空隙,于是花了點時間研究了下。
雖然蘋果出了ARC(自動內存管理機制),我們不用花太多的時間在內存泄漏的問題上,但在我們開發的過程中,還是會因為各種原因而產生內存泄漏,例如Block的循環引用,delegate 寫成了 strong,定時器沒有關閉,弱指針使用不當等等。
所以我們下面就簡單介紹下怎么使用Xcode8自帶的Instruments中的Leaks檢測我們的程序有沒有內存泄露和定位內存泄露的代碼,讓我們可以更準確的定位和解決問題
(分析內存泄露不能把所有的內存泄露查出來,有的內存泄露是在運行時,用戶操作時才產生的)
Leaks具體使用
leaks如何使用?寫的比較詳細,步驟也很簡單,感謝網友分享方便瀏覽,下面也簡單的寫下步驟
1、打開Leaks(兩種方式)
方式一:
方式二:
2、使用Leaks
完成步驟1之后,就能看到我們應用的體檢結果了(這里僅僅指內存泄漏;點擊那個紅叉標識顯示具體的leaks,如下圖)
哇,運行應用之后,還沒操作頁面呢,就這么多內存泄漏,也難怪模擬器跑的時候內存占用那么多。問題是找出來,但是這樣的信息真的看不懂啊,怎么辦呢?不急,其實很簡單,設置一個地方就好。
3、設置Leaks,查找定位具體leak是什么
現在我們就能看出個大概究竟了,我這個項目里一看就知道是自己封裝的AFNeteworking有問題。當然此時你還可以選中某一條雙擊,就能定位到具體代碼處,如下圖.
4、解決leak
后來仔細看了下該文件的這個方法,不難發現確實有問題。(注意注釋if語句,若不加if語句,每次請求接口都創建一個session對象,又沒釋放,那自然就造成了內存泄漏。還有session的一些設置里面,道理也是一樣。)
//數據請求,post和get
- (void)requestWithMethod:(RequestMethod)requestMethod
andUrlString:(NSString *)urlString
andParameters:(id) parameters
success:(CompletePost)success
failure:(CompleteFailure)failure
{
//session存在的話,不需要重復創建該對象,解決內存leak問題
// if (!session) {
session = [AFHTTPSessionManager manager];
//設置自定義代理參數
[session.requestSerializer setValue:[StaticTools setUserAgentWithParam:@"afn"] forHTTPHeaderField:@"User-Agent"];
session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"multipart/form-data",@"text/plain", nil];
//配置https
session.securityPolicy = [self customSecurityPolicy];
session.securityPolicy.allowInvalidCertificates = YES;
// }
if (requestMethod == get) {
//[self addParaWithOriginDic:parameters] ,判斷參數是否帶token,若有的話 添加隨機數和簽名參數
[session GET:urlString parameters:[self addParaWithOriginDic:parameters] progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
}];
} else {
[session POST:urlString parameters:[self addParaWithOriginDic:parameters] progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
if (error.code == -1001) {
//做超時之后的一些操作
}
}];
}
}
放開if之后,再次檢測,發現之前那么多leaks都不見了,果真是這個問題導致。(下圖雖然還有leak,但是一看就知道是集成的第三方微客服那邊的問題,已反饋)
結果
再次在模擬器上跑的時候,發現內存確實也小了很多,70的樣子,比之前的130多確實少多了(真機上運行內存在40的樣子)
結語:存在leaks雖然貌似不會影響App的審核,平時用的時候也沒出現奔潰,但是干掉leaks,能健壯咋們的app,減少應用奔潰閃退的概率,挺好!