起因:
AFURLSessionManager實現(xiàn)了NSURLSession的協(xié)議,即AFURLSessionManager和NSURLSession互相持有,如果這個delegate是week的話隧哮,那沒什么問題,但是系統(tǒng)提供的是retain:如圖
所以里面是有循環(huán)引用的苔严。一旦使用非單例的方式來使用AFHTTPSessionManager,如果不做特殊處理每瞒,就會導致這個對象在應(yīng)用存活期間是不會銷毀的,如果應(yīng)用網(wǎng)絡(luò)請求過多纯露,用戶反復進入各種vc剿骨,內(nèi)存泄漏明顯。這明顯不安全埠褪。
解決方案一:把該manager封裝成單例
方案代碼:
static AFHTTPSessionManager *manager;
/* 封裝成 單例會話管理者 */
+ (AFHTTPSessionManager *)sharedManager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 初始化請求管理類
manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
// 設(shè)置15秒超時 - 取消請求
manager.requestSerializer.timeoutInterval = 15.0;
// 編碼
manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
// 緩存策略
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
manager.responseSerializer = [AFJSONResponseSerializer serializer];
// 支持內(nèi)容格式
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/plain", @"text/javascript", @"text/json", @"text/html", nil];
});
return manager;
}
問題:很明顯浓利,同一時刻只能有一個網(wǎng)絡(luò)請求。異步會有問題钞速。當兩個線程同時申請manager對象時贷掖,肯定有一個manager申請不到,無法網(wǎng)絡(luò)請求
解決方案二:在網(wǎng)絡(luò)請求的block內(nèi)把task取消掉
無論是success渴语,還是failure的回調(diào)都取消掉苹威,當然在block外部需要弱化一下manager對象
__weak typeof(manager) weakManager = manager;
然后在兩個回調(diào)方法里加上
[weakManager invalidateSessionCancelingTasks:YES resetSession:YES];
具體代碼如下:
兩種方案都可以解決內(nèi)存泄漏問題。推薦第二種驾凶,封裝在某個網(wǎng)絡(luò)請求基類里牙甫,或者每次網(wǎng)絡(luò)請求結(jié)束都寫上。