好吧吞瞪,雖然標(biāo)題是和AFN有關(guān)眼刃,而本人也非常喜歡用AFN這個(gè)庫破托,但是今天使用leaks測(cè)試了一下發(fā)現(xiàn)所有出現(xiàn)紅XX的地方全部都是和AFN有關(guān)颊乘,如果你使用了AFN而且使用leaks測(cè)試了你可能就會(huì)出現(xiàn)下面的這張圖:
好吧紅xx那張圖我就不截圖了骚亿,實(shí)在沒心情看已亥,你們可以看到圖中所有的內(nèi)存泄露都和NSURLSession有關(guān)。
還是回到今天的主題吧来屠,大家使用AFN都會(huì)基于AFN進(jìn)行二次封裝虑椎,(這個(gè)毋庸置疑吧,額俱笛,要是不封裝的別打臉)捆姜,估計(jì)很多人封裝AFN的時(shí)候都是這樣的:
#pragma mark - /*** 單例方法 ***/
static id _instance;
+ (instancetype)shareManager{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
return _instance;
}
這是一個(gè)單例木有錯(cuò),但是很多人封裝請(qǐng)求方法的時(shí)候又是這樣的:
#pragma mark - /*** POST請(qǐng)求 ***/
- (void)postWithURL:(NSString *)url parameters:(NSDictionary *)para sucess:(AFSuccessCall)sucess failure:(AFFailCall)failure
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json",@"text/json", @"text/javascript",@"text/plain",nil];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:url parameters:para constructingBodyWithBlock:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (sucess) {
sucess(responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) {
failure(error);
}
}];
}
好吧迎膜,終于要說到重點(diǎn)了泥技,請(qǐng)注意這一行:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
這一看就像是一個(gè)單例沒錯(cuò)吧,其實(shí)我也是這么覺得的磕仅,但是珊豹、但是、但是(你懂得)榕订。出現(xiàn)內(nèi)存泄露的根源就是這個(gè)家伙店茶,它只是一個(gè)類方法(真的只是一個(gè)類方法),所以我們只要有網(wǎng)絡(luò)請(qǐng)求 都會(huì)實(shí)例化一個(gè)對(duì)象出來劫恒,后果可想而知贩幻,那解決方案就不用我說了吧:將它封裝成一個(gè)單例吧!至于怎么整一個(gè)單例出來我就不寫了(不懂得自糾小GG)