使用AFNetworking时, 控制器点击返回销毁了, 但还是会执行请求成功或失败的block, 导致野指针异常

时间:2021-03-15 12:37:13

原本我以为是我程序框架有问题...后来才知道, 无知真可怕...

__unsafe_unretained __block typeof(self) weakSelf = self;

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
manager.requestSerializer.timeoutInterval = 30; [manager POST:URLString parameters:params constructingBodyWithBlock:block progress:uploadProgress success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if (responseObject) {
// 操作固定数据
[weakSelf operationWithSessionId:responseObject[@"sessionid"]
userInfo:responseObject[@"userInfo"]
shopCartNum:responseObject[@"shopcartnum"]
secret:responseObject[@"secret"]]; success(task, responseObject);
} else {
[SVProgressHUD dismiss];
RPLog(@"请求的链接有问题");
} } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(task, error);
}];

大家都知道, 在block里面使用self会形成循环引用, 所以我这里就使用__unsafe_unretained __block typeof(self) weakSelf = self; 来避免,

但是在每次发出请求后(请求结果还没有返回时), 我点导航栏上的返回, 就会出现野指针异常...我就纳闷了...控制器也有被销毁呀...为什么还会调用请求完成后的block呢?

也就是说, 控制器太早被销毁了...所以导致请求完后的block访问了野指针...

后来自己瞎搞了一个方法, 方法如下:

出现这个问题, 是因为控制器太早销毁..那么我就在block里面使用self而不是weakSelf, 让block对self进行一个强引用, 然后等请求完成后的block销毁, 控制器才会销毁..

但这样做的弊端就是会导致内存泄露, 虽然我在测试的时候, 请求发送出去, 点返回, 请求完成, 控制器也随之销毁...我猜可能是AFNetworking这框架对请求完成后的block的生命周期有做一些优化..

注意, 我说是我猜的!!我也不知道是不是这样...

虽然暂时解决了问题...但是内心还是很难受...因为总感觉哪里不对劲...所以就有了第二种解决方法...

就是__unsafe_unretained __block typeof(self) weakSelf = self;换成__weak typeof(self) weakSelf = self; 问题就解决了!!!

然后我网上找了下这两者的区别..

具体可以看看这里~~~

http://www.it165.net/pro/html/201410/24001.html