好吧,虽然标题是和AFN有关,而本人也非常喜欢用AFN这个库,但是今天使用leaks测试了一下发现所有出现红XX的地方全部都是和AFN有关,如果你使用了AFN而且使用leaks测试了你可能就会出现下面的这张图:
好吧红xx那张图我就不截图了,实在没心情看,你们可以看到图中所有的内存泄露都和NSURLSession有关。
还是回到今天的主题吧,大家使用AFN都会基于AFN进行二次封装,(这个毋庸置疑吧,额,要是不封装的别打脸),估计很多人封装AFN的时候都是这样的:
#pragma mark - /*** 单例方法 ***/
static id _instance;
+ (instancetype)shareManager{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
return _instance;
}
这是一个单例木有错,但是很多人封装请求方法的时候又是这样的:
#pragma mark - /*** POST请求 ***/
- (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);
}
}];
}
好吧,终于要说到重点了,请注意这一行:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
这一看就像是一个单例没错吧,其实我也是这么觉得的,但是、但是、但是(你懂得)。出现内存泄露的根源就是这个家伙,它只是一个类方法(真的只是一个类方法),所以我们只要有网络请求 都会实例化一个对象出来,后果可想而知,那解决方案就不用我说了吧:将它封装成一个单例吧!至于怎么整一个单例出来我就不写了(不懂得自纠小GG)