Alamofire 的坑

这周在开始写东西的时候遇到了很多的坑,首先就是网络请求异步的问题.
整理了一下思路.传值主要使用了以下的两种思路.

我们在进行网络请求时.在使用 Alamofire 和 AFNetWorking 的时候都是在进行异步请求.
举个栗子 :

闭包传值

  #define  MapAnalyzeBaseURL "http://restapi.amap.com/v3/geocode/regeo?"
  #define  MapAnalyKey  "&key=e8ba6e7f8fd9699f47affcd525f1f300"
  #import "AFNetHelper.h"
  @implementation AFNetHelper
  -(void)setNetWorkHelpercompletionHandler: ( void (^) (id))Myblock{
     NSURLSession *configuration = [NSURLSessionConfiguration defaultSessionConfiguration ];
     AFURLSessionManager *manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:configuration];

     NSString *URLString = @MapAnalyzeBaseURL;
     NSDictionary *paramters = @{@"output":@"JSON",@"location":@"116.310003,39.991957",@"key":@"e8ba6e7f8fd9699f47affcd525f1f300",@"radius":@"1000",@"extensions":@"all" };
    
     NSMutableURLRequest * request = [[AFHTTPRequestSerializer serializer]requestWithMethod:@"GET" URLString:URLString parameters:paramters error:nil ];



     NSURLSessionDataTask * task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
          if(error){
                  NSLog(@"error");
          }else{
                   NSLog(@"%@",responseObject);
                    Myblock(responseObject);
                  }];
     [task resume];

  }

@end

这里有一段网络请求,我们需要请求后返回的数据.但是死活就是拿不到数据.可能你打断点到responeObject 会发现已经有了值,但是你在这个里面想把值传出去.你会发现很难传出去,

一些传值时候的错误想法

假设你现在进行了网络请求 ,拿到了一个JSON数据这个数据解析出来是一个数组.接着你想要把这个数组传出去.可能要去更新你的界面.接着就自然而然的定义了一个类属性,然后想当然的就会写赋值语句.既然我需要这个值,那么直接赋值给一个类属性.然后再用这个属性来对界面进行更新.一切都是很自然的事情.当你把一切都做好了,开始运行的时候,会发现程序除了问题.再用类属性对界面赋值的时候.你会发现控制台显示你的这个属性是空? WHY? 这为什么是空的

举个栗子

给网络请求的部分打上断点

接着执行这个命令,你会发现很有意思的事情

执行到断点一

这很正常╮(╯﹏╰)╭ 多简单就是这么随意 ,接着开始执行下一行.

执行断点二

( ⊙o⊙?)不懂 这是怎么回事,为什么前面的这些断点都没执行,直接就结束了?怎么回事,为什么不执行,顺序执行,多简单的事啊,为什么不执行.思前想后,无解.

接下来很小心的检查了一下成功后的数据,发现,我数据已经拿了回来.而且也已经赋值给了全局属性.那为什么就是没有值呢?

这还要从刚才那个程序不顺序执行,直接返回结果开始说.这个网络请求是异步的.所以它会在其他的线程去执行.而不是主线程,所以它直接把网络请求扔给了其他线程去做,然后程序跳过这段继续进行.因为这个时候网络请求并没有被执行,所以我们的类属性中的值是空的,这个时候去用这个类属性值去更新界面上的一些东西.会出错.程序出BUG了

既然已经有了问题,我们应该怎么去解决?

解决方法一:

既然网络请求没有执行,那么我们就等网络请求执行完,我们的类属性已经拿到了数据之后再更新界面.
在swift 中有一种属性叫 Property Observers(监视器属性)开始的时候设置一个默认值,然后当值改变的时候,去更新界面

举个栗子

var weekWeather = [Daily](){
    didSet{
        self.setNowWeather() 
    }
}

Alamofire.request(.GET, url).validate().responseJSON { respon in
  if let dic = respon.result.value as? NSDictionary {
      if let newDic = dic["HeWeather data service 3.0"]?.firstObject as? NSDictionary{
           if let weatherArray = newDic["daily_forecast"] as? NSArray{
               let daily = Mapper<Daily>().mapArray(weatherArray)
               print(daily?.count)
               self.weekWeather += daily!
             }
       }
   }
}  

解决方法二

我们对整个网络请求的部分进行封装.添加闭包,用闭包来解决传值的问题 .就是我们最开始写的那个闭包传值.
这个部分有两个地方值得大家注意

函数的声明部分

首先我们声明了这个函数接受一个闭包类型.这个闭包接受id类型的参数,返回值为空

接下来我们要执行这个闭包

闭包的执行部分

当我们成功的拉取到了网络的数据的时候,执行这个闭包. (ˉ▽ ̄~) 切~~,声明了执行了又怎么样,你的执行代码呢,你连一行执行的代码都没写,还执行闭包.能执行才出鬼了.

接下来就是闭包的执行部分


开始执行闭包

这里因为我的工程里面是oc 和 swift 混编,但是基本的思想是一样的,我创建了一个类的实例(刚开始写的那个类).然后执行了我声明的方法,最最关键的地方到了.我们这里接受一个闭包的参数!!!.还记得我们执行闭包的时候的那个参数么,这个时候闭包就把这个参数拿到了.而且参数是有值得.因为不需要这个闭包有返回值.只是要拿到网络请求的结果responseObject.这是一个id类型的变量.在这个闭包里面.data 指的就是这个 responseObject. 可能有人问这是怎么看出来的

       Myblock(responseObject);

还记得我们这行代码么,这行代码就是闭包接受的参数.我们已经给了一个参数叫
responseObject.然后在闭包执行的时候

   a.setNetWorkHelpercompletionHandler{ data in

这个data 就是我们抓取到的responseObject.这样,我们就拿到数据了.接下来就可以在这个闭包中更新你的类属性,然后更新你的界面了.

总结

网络请求异步的问题在开发中很常见,开始不能赋值的问题纠结了好几天,最终发现这个api是异步的,并不会直接执行.所以我们在使用一些异步的API的时候需要注意传值的问题.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,937评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,924评论 25 707
  • 《七绝·风灵》 轻揉慢捻去寒酥, 温润潮清浣冷湖。 意染踯躅千万里, 翩翾陌上觅於菟。 【平水韵:上平七虞】 转载...
    我那纷纷的思欲阅读 513评论 0 0
  • 2017.5.3星期三 终于通过客服约到厚街万达的经理,答应面谈下。 这几天,我的无名火很多,尤其是回到家里,给孩...
    annaqueen阅读 103评论 0 0