ASI网络请求在debug可用,发布项目后不能发送网络请求

最近做项目用到了ASI发送网络请求。遇到这么个情况之前没遇到过的,就是发送一个网络请求,需要用到请求回来的响应数据显示在tableview上面,代码是这么写的

 __weak  ASIHTTPRequest * formlogin=[ASIHTTPRequest requestWithURL:url];

    formlogin.timeOutSeconds=60;

    formlogin.delegate=self;


    [formlogin setCompletionBlock:^{

        NSString * fanhui=[formlogin responseString];

        NSMutableDictionary * dic= [self dictionaryWithJsonString:fanhui];

        //    NSLog(@"**********%@",dic);

        NSDictionary * response=[[NSDictionary alloc]init];

        NSArray * dataArr=[[NSArray alloc]init];

        response=[dic objectForKey:@"response"];

        NSString * code=[NSString stringWithFormat:@"%@",[response objectForKey:@"code"]];

        if ([code isEqualToString:@"0"]) {

            dataArr=[dic objectForKey:@"data"];

            

            LinenumberViewController * ltvc = [[LinenumberViewController alloc]init];

            if (dataArr != nil) {

                ltvc.dataArr=dataArr;

                

                __weak AddCardViewController * weak=self;

                ltvc.changeBlock1=^(NSString * bankcode,NSString * bankname){

                    weak.linenumberLab.text=bankname;

                    weak.branchName=bankname;

                    weak.branchId=bankcode;

                } ;

                [self.navigationController pushViewController:ltvc animated:YES];

            }

            else{

                NSLog(@"城市数组和城市编码数组为空了");

            }

        }

    }];

    [request1 setFailedBlock:^{

        NSLog(@"hehe");

    }];

    

    [request1 startAsynchronous];

注意上面的网络请求的ASIhttpRequest实例化为formlogin对象,下面用到了block方法,因为怕引起循环引用,所以实例化时前面加了__weak,这样做在测试时是没有问题的,可是项目发布之后该方法的setcomplete回调是不起作用的,究其原因,查了一下相关资料,贴在下面:

http://blog.csdn.net/fengsh998/article/details/38090205

大体的意思就是,在实例化时不加__weak其实在ARC中会产生(Capturing 'demo' strongly in this block is likely to lead to a retain cycle)告警。为了消除这个警告加上__weak,说这是一个WEAK变量,就马上会被release。因此就不会执行block中的内容。

那么怎么去除掉这种危险呢?有几种解决办法:(当然是针对这种情况而非此项目):

ASIHTTPRequest * formlogin=[ASIHTTPRequest requestWithURL:url];

    formlogin.timeOutSeconds=60;

    formlogin.delegate=self;

    __weak ASIHTTPRequest * request1=formlogin;

    [request1 setCompletionBlock:^{

        NSString * fanhui=[request1 responseString];

        NSMutableDictionary * dic= [self dictionaryWithJsonString:fanhui];

        //    NSLog(@"**********%@",dic);

        NSDictionary * response=[[NSDictionary alloc]init];

        NSArray * dataArr=[[NSArray alloc]init];

        response=[dic objectForKey:@"response"];

        NSString * code=[NSString stringWithFormat:@"%@",[response objectForKey:@"code"]];

        if ([code isEqualToString:@"0"]) {

            dataArr=[dic objectForKey:@"data"];

            

            LinenumberViewController * ltvc = [[LinenumberViewController alloc]init];

            if (dataArr != nil) {

                ltvc.dataArr=dataArr;

                

                __weak AddCardViewController * weak=self;

                ltvc.changeBlock1=^(NSString * bankcode,NSString * bankname){

                    weak.linenumberLab.text=bankname;

                    weak.branchName=bankname;

                    weak.branchId=bankcode;

                } ;

                [self.navigationController pushViewController:ltvc animated:YES];

            }

            else{

                NSLog(@"城市数组和城市编码数组为空了");

            }

        }

    }];

    [request1 setFailedBlock:^{

        NSLog(@"hehe");

    }];

    

    [request1 startAsynchronous];

在上面的实例化时,不加_-weak,在下面块将引入时,用__weak的实例来引入,带入到block中,这样就可以了

因此,写这个主要用来告戒一些喜欢用BLOCK但又想当然的朋友,有一些朋友喜欢去除告警,但只是盲目的加上__weak 或__block关键语,往往可能存在一些重大的安全隐患。就像演示中block根本不走。如果到了发布时,为了去告警而这样简单的处理了,并没有进行测试就打包。哪么将死得很惨。。。。。


好,到了尾声,来说说为什么朋友问我block会不会引行死循环,我说不会的理由。

见码:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. - (IBAction)onTest:(id)sender  
  2. {  
  3.     BlockDemo *demo = [BlockDemo blockdemo];//[[BlockDemo alloc]init];  
  4.       
  5.     [demo setExecuteFinishedParam:^(BlockDemo * ademo) {  
  6.         if (ademo.resultCode == 200) {  
  7.             NSLog(@"call back ok.");  
  8.         }  
  9.     }];  
  10.       
  11.     [demo executeTest];  
  12. }  

不管是在外面init,还是在里面,且没有加__block 及__weak。为什么,因为我个人常常在使用自己写的block时,如果是回调,比较喜欢把自身当作参数传到block中。这样期实是编译器给我们做了弱引用。因此不会产生循环引用。

最后,针对此情况,在此项目中,我找到了三种解决办法,上面的是第一种解决办法,第二章则是用ASI的代理方法

  ASIHTTPRequest * request0=[ASIHTTPRequest requestWithURL:url];

    

    NSLog(@"1");

        request0.timeOutSeconds=60;

    NSLog(@"2");

        request0.delegate=self;

    NSLog(@"3");

     mudata=[[NSMutableData alloc]init];

       [request0 startAsynchronous];

这个是实例化网络请求发送请求,在回调处处理返回的数据,而不是在本方法中处理。具体请查看代理方法,在此略过。

第三种方法:不使用ASIhttprequest,而是使用ASIformdatarequest。

ASIFormDataRequest * formlogin=[ASIFormDataRequest requestWithURL:url];

//    formlogin.timeOutSeconds=60;

//    formlogin.delegate=self;

//   __weak ASIFormDataRequest * request1=formlogin;

//    [request1 setCompletionBlock:^{

//        

//        NSLog(@"呵呵");

//        NSString * fanhui=[request1 responseString];

//        NSMutableDictionary * dic= [self dictionaryWithJsonString:fanhui];

//        //    NSLog(@"**********%@",dic);

//        NSDictionary * response=[[NSDictionary alloc]init];

//        NSArray * dataArr=[[NSArray alloc]init];

//        response=[dic objectForKey:@"response"];

//        NSString * code=[NSString stringWithFormat:@"%@",[response objectForKey:@"code"]];

//        if ([code isEqualToString:@"0"]) {

//            dataArr=[dic objectForKey:@"data"];

//            

//            LinenumberViewController * ltvc = [[LinenumberViewController alloc]init];

//            if (dataArr != nil) {

//                ltvc.dataArr=dataArr;

//                

//                __weak AddCardViewController * weak=self;

//                ltvc.changeBlock1=^(NSString * bankcode,NSString * bankname){

//                    weak.linenumberLab.text=bankname;

//                    weak.branchName=bankname;

//                    weak.branchId=bankcode;

//                } ;

//                [self.navigationController pushViewController:ltvc animated:YES];

//            }

//            else{

//                NSLog(@"城市数组和城市编码数组为空了");

//            }

//        }

//    }];

//    [request1 setFailedBlock:^{

//        NSLog(@"hehe");

//    }];

//

//    [request1 startAsynchronous];

这样也可以的,有的地方有朋友可能不懂事干嘛的,我这个是从后台请求回来的银行列表数据,和对应的银行编码code。使之按条件搜索显示在tableview上,大体就是这样了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值