美文网首页
解决iOS AFNetworking内存泄漏的两种方式

解决iOS AFNetworking内存泄漏的两种方式

作者: 东北小小猿 | 来源:发表于2018-12-03 16:39 被阅读16次

CR.MO Blog 参考文章地址

解决方式


1.利用单例

利用单例 避免多次创建
优点
对于客户端来说,大多数情况下都是对应同一个后台服务,所以保持session可以减少http三次握手
缺点
<1> http的header是 AFHTTPSessionManager的requestSerializer.mutableHTTPRequestHeaders字典持有,所以单列的模式会导致全局共享一个header,对要求不同请求自定义header的请求很麻烦
<2> 异步同时请求时会有问题(但是我还没有遇到过)
-(AFHTTPSessionManager *)shareManager{
    static dispatch_once_t onceToken;
    static AFHTTPSessionManager *_manager = nil;
    dispatch_once(&onceToken, ^{
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil];
        _manager.requestSerializer = [AFHTTPRequestSerializer serializer];
        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"text/json", @"text/plain", @"text/javascript",@"text/xml", nil];
        _manager.requestSerializer.timeoutInterval = 30;
        _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    });
    return _manager;
}

2 关闭session

在AF的回调中 利用manager 关闭session
注意 :session一旦关闭了, manager 就不能再次发起请求了
-(AFHTTPSessionManager *)getSessionManager{
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"text/json", @"text/plain", @"text/javascript",@"text/xml", nil];
    manager.requestSerializer.timeoutInterval = 30;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    return manager;
}

-(void)sendRequest{
    AFHTTPSessionManager *manager = [self getSessionManager];
    __weak typeof(manager)weakManager = manager;
    [manager GET:@"https://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
         __strong typeof (weakManager)strongManager = weakManager;
        NSLog(@"success回调");
        [strongManager invalidateSessionCancelingTasks:YES];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        __strong typeof (weakManager)strongManager = weakManager;
        NSLog(@"error回调");
        [strongManager invalidateSessionCancelingTasks:YES];
    }];
}


测试代码:

#import "ViewController.h"
#import <AFNetworking.h>
#import <objc/runtime.h>

@interface ViewController ()
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self _exchangeImp];
}
- (IBAction)btnClick:(id)sender {
    [self sendRequest];
}

-(AFHTTPSessionManager *)getSessionManager{
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"text/json", @"text/plain", @"text/javascript",@"text/xml", nil];
    manager.requestSerializer.timeoutInterval = 30;
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    return manager;
}

-(void)sendRequest{
    AFHTTPSessionManager *manager = [self getSessionManager];
    __weak typeof(manager)weakManager = manager;
    [manager GET:@"https://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
         __strong typeof (weakManager)strongManager = weakManager;
        NSLog(@"success回调");
        [strongManager invalidateSessionCancelingTasks:YES];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        __strong typeof (weakManager)strongManager = weakManager;
        NSLog(@"error回调");
        [strongManager invalidateSessionCancelingTasks:YES];
    }];
}

-(void)_exchangeImp{
    Method methodA = class_getInstanceMethod([AFHTTPSessionManager class], NSSelectorFromString(@"dealloc"));
    Method methodB = class_getInstanceMethod([self class], @selector(deallocExchage));
    method_exchangeImplementations(methodA, methodB);
}

-(void)deallocExchage{
    NSLog(@"AFHTTPSessionManager dealloc");
}



-(AFHTTPSessionManager *)shareManager{
    static dispatch_once_t onceToken;
    static AFHTTPSessionManager *_manager = nil;
    dispatch_once(&onceToken, ^{
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil];
        _manager.requestSerializer = [AFHTTPRequestSerializer serializer];
        _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html",@"text/json", @"text/plain", @"text/javascript",@"text/xml", nil];
        _manager.requestSerializer.timeoutInterval = 30;
        _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    });
    return _manager;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

相关文章

网友评论

      本文标题:解决iOS AFNetworking内存泄漏的两种方式

      本文链接:https://www.haomeiwen.com/subject/gvwycqtx.html