在使用instruments作內存泄漏分析時,發現全部使用以下語句的地方都有內存泄漏,OMG:安全
leaks上圖: bash
if (!_manager) {
_manager = [AFHTTPSessionManager manager];
}
複製代碼
緣由:session在ARC下不會及時釋放網絡
我所用到的網絡請求不是很複雜,不想再新建類去寫單例了,就把單例放在了AppDelegate中,用到的時候在經過AppDelegate拿。由於須要用到AFURLSessionManager,因此就寫一個單例方法。session
static AFHTTPSessionManager *manager ;`
-(AFHTTPSessionManager *)sharedHTTPSession{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [AFHTTPSessionManager manager];
manager.requestSerializer.timeoutInterval = 10;
});
return manager;
}
複製代碼
可是 作成單例並非很好的方式,能夠在AFAppDotNetAPIClient中的dealloc中手動觸發sessionManager.session.finish...()釋放session的delegete,打破AF內部的循環引用ui
完美解決 @·@
緣由探究: AFURLSessionManager
實現了NSURLSession
的協議,即AFURLSessionManager
和NSURLSession
互相持有,若是這個delegate是week的話,那沒什麼問題,可是系統提供的是retain:如圖spa
因此裏面是有循環引用的。一旦使用非單例的方式來使用AFHTTPSessionManager,若是不作特殊處理,就會致使這個對象在應用存活期間是不會銷燬的,若是應用網絡請求過多,用戶反覆進入各類vc,內存泄漏明顯。這明顯不安全。code
好在AFN和NSURLSession都有方法能夠解決:cdn
//廢棄session對象。cancelPendingTasks決定是否取消此session中的tasks
–(void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks
複製代碼
方法二:對象
__weak typeof(manager) weak_manager = manager;
[manager requestWithMethod:method
URLString:uri
parameters:param
success:^(NSURLSessionDataTask *task, id responseObject) {
if (completion) {
completion(YES, responseObject, task.response);
}
[weak_manager invalidateSessionCancelingTasks:YES];
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
if (completion) {
completion(NO, error, task.response);
}
[weak_manager invalidateSessionCancelingTasks:YES];
}];
複製代碼