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

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

__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

时间: 2024-10-29 19:09:46

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

Android点击返回键back时弹出对话框Dialog

public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { ExitDialog(MainActivity.this).show(); return true; } return super.onKeyDown(keyCode, event); } private Dialog ExitDialog

查看SharePoint文档库是,显示层次目录,可以点击返回层次

在sharepoint 2013中,Documnet library(文档库)包含多层文件夹,当进入到文件夹后,返回指定层次了(例如返回上一层),需要用浏览器的返回. 使用起来不方便,而且浏览器的返回,会导致一些问题,不推荐普遍用户使用. 解决这个问题,可以做一个目录结构,实现方法是:访问Document library 时, url 有个参数[RootFolder],记录了路径. 主要对[RootFolder]参数进行处理. 这里使用webpart实现.当然,也可以Javascript方式实现

按钮显示PopupWindow,setOutsideTouchable(true)时,点击按钮再次打开的问题

先给大家看看这个:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E7%9F%A5%E8%AF%86%E5%BA%93/21462.shtml 可以说我也是受到了一点这个的启发,虽然我的思路和这很不一样,记录下. 我没有去试上面的方法,但看着应该也可以,但是我觉得不太妥,所以没有用,大家想法不一样,所以也贴上给大家看看,同时也感谢大神的提醒. 同求有更多,更好想法的人相互分享!! ok,废话不多说,进入正题: 问题是这样,我在界面的个bu

解决在 使用 AjaxFileUploder 插件时,不能获取返回的 json 结果数据

在MVC  项目 中使用 AjaxFileUploader 这个插件时,在上传图片或文件时,在控制器中返回的是 json数据,可是在 ie,或 googleChrome 浏览器中却出现 返回的json数据下载的情况,针对 这个情况,以下是我自己解决的方法: 需要特别注意两个地方: 1. 在返回的 json 数据时,加上 "text/html" 这个参数 return Json(new { success = true, originalName = OriginFileName, or

android webview点击返回键返回上一级activity

android webview点击返回键返回上一个activity 1 @Override 2 public boolean onKeyDown(int keyCode, KeyEvent event) { 3 // TODO Auto-generated method stub 4 if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { 5 return true; 6 } 7 return super

点击返回键退出popupwindow的方法

点击返回键退出popupwindow mPopupWindow.setFocusable(true); 这句非常重要,对背景不会有影响 mPopupWindow.setBackgroundDrawable(new BitmapDrawable()); 然后再设置它的键监听器 mView.setOnKeyListener(onKeyListener); private OnKeyListener onKeyListener=new OnKeyListener() { @Override publi

点击返回上一页代码实例

点击返回上一页代码实例:在网页中,经常见到这么一个效果,点击一个按钮.文本或者图片可以返回上一步所浏览的网页,下面就给出代码实例,希望能够给需要的朋友带来帮助,代码实例如下:一.点击按钮返回上一页: <input type="button" onclick="javascript:history.back(-1);" value="返回上一页" /> 二.点击图片返回上一页: <img src="images/bt.j

android webview点击返回键回到上一个html

android webview点击返回键返回上一个html 1 @Override 2 public boolean onKeyDown(int keyCode, KeyEvent event) { 3 if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) { 4 mWebView.goBack();// 返回前一个页面 5 return true; 6 } 7 return super.onKeyDown(keyCod

在微信、支付宝、百度钱包实现点击返回按钮关闭当前页面和窗口

最近在使用微信.支付宝.百度钱包实现网页支付,对支付成功将自动关闭页面,对于支付失败,将显示错误信息.当在错误页面的时候,点击返回 或者Android物理按键上一步的时候,将关闭页面. 在微信.支付宝.百度钱包中,他们对页面关闭进行了封装,传统的window.close()是无效的,必须要使用它们的js代码才能关闭.下面是三种移动app 的关闭方式: WeixinJSBridge.call('closeWindow');//微信 AlipayJSBridge.call('closeWebview