[转载]AFNtworking同步请求解决方法

很多时候我们在做网络请求的时候,往往要拿到数据后才能去处理进一步的操作。但是,AFNetworking
并没有同步的方法,那么我们应该怎么处理呢?

方法一:


- (void)getWeatherData
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.requestSerializer     = [AFJSONRequestSerializer serializer];
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

        __block dispatch_semaphore_t sem = dispatch_semaphore_create(0);
        __block BOOL isSuccess           = NO;
        __block NSDictionary *json       = nil;

        [manager GET:@"http://www.weather.com.cn/data/sk/101010100.html"
          parameters:nil
             success:^(NSURLSessionDataTask *task, id responseObject)
        {
            NSLog(@"加载成功 %@",responseObject);

            isSuccess = YES;

            if ([responseObject isKindOfClass:[NSDictionary class]]) {
                json = responseObject;
            }

            dispatch_semaphore_signal(sem);

        } failure:^(NSURLSessionDataTask *task, NSError *error) {

            NSLog(@"加载失败 %@",error);

            isSuccess = NO;

            dispatch_semaphore_signal(sem);
        }];

        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

        dispatch_async(dispatch_get_main_queue(), ^{

            /* 回到主线程做进一步处理 */

            if(isSuccess) {

                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"请求成功" message:[NSString stringWithFormat:@"%@",json] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
                [alert show];
            }
        });
    });
}

方法二:


- (void)getWeatherData
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        NSCondition *condition = [[NSCondition alloc] init];

        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.requestSerializer     = [AFJSONRequestSerializer serializer];
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

        __block BOOL isSuccess           = NO;
        __block NSDictionary *json       = nil;

        [manager GET:@"http://www.weather.com.cn/data/sk/101010100.html"
          parameters:nil
             success:^(NSURLSessionDataTask *task, id responseObject)
         {
             NSLog(@"加载成功 %@",responseObject);

             isSuccess = YES;

             if ([responseObject isKindOfClass:[NSDictionary class]]) {
                 json = responseObject;
             }

             [condition lock];
             [condition signal];
             [condition unlock];

         } failure:^(NSURLSessionDataTask *task, NSError *error) {

             NSLog(@"加载失败 %@",error);

             isSuccess = NO;

             [condition lock];
             [condition signal];
             [condition unlock];
         }];

        [condition lock];
        [condition wait];
        [condition unlock];

        dispatch_async(dispatch_get_main_queue(), ^{

            /* 回到主线程做进一步处理 */

            if(isSuccess) {

                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"请求成功" message:[NSString stringWithFormat:@"%@",json] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
                [alert show];
            }
        });
    });
}

方法三:


- (NSDictionary *)getJsonData
{
    NSString *url = [NSString stringWithFormat:@"请求的url字符串"];

    /* 请求参数字典 */
    NSMutableDictionary *requestParms = [[NSMutableDictionary alloc] init];
    [requestParms setObject:@"value" forKey:@"key"];

    AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
    NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"POST" URLString:url parameters:requestParms error:nil];

    /* 最终继承自 NSOperation,看到这个,大家可能就知道了怎么实现同步的了,也就是利用 NSOperation 来做的同步请求 */
    AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    AFHTTPResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];

    [requestOperation setResponseSerializer:responseSerializer];

    [requestOperation start];

    [requestOperation waitUntilFinished];

    /* 请求结果 */
    NSDictionary *result = (NSDictionary *)[requestOperation responseObject];

    if (result != nil) {

        return result;
    }
    return nil;
}


小结

使用上面任意一种方法都可以解决AFNetworking同步请求的操作。需要注意的是,前两种方法中请求要放在异步线程执行,否则会死锁,在请求结束后再回到主线程执行。

上半部分内容转载自:AFNtworking同步请求解决方法
作者:jixuqianxing

Postscript:

  • 使用AFNetworking时,程序会先执行网络请求,后直接往前走到方法的return,在之后才会执行完block内部的内容,故而需要方法的返回值时需慎重;
  • 第一种阻塞线程实现网络请求同步的做法测试了下发现无效,分析原因可能为先进行网络请求,然后直接执行到dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);,此时未接收到dispatch_semaphore_signal(sem);的信息,而当该语句执行的时候该方法已经运行结束,故无法接着执行return操作
  • 后面方法未测,目前先采用同步网络请求进行操作,后面有时间再行测试
  • 如有遗漏错误之处欢迎指正
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • 谈到iOS多线程,一般都会谈到四种方式:pthread、NSThread、GCD和NSOperation。其中,苹...
    攻城狮GG阅读 260评论 0 3
  • 1.何为多线程 多线程是一个应用程序同时执行多个任务,线程是执行程序的最基本单元,他有自己的栈和寄 存器,线程既是...
    随意啊阅读 87评论 0 0
  • 婚姻的魔掌终于伸过来了,伸过来了……过来了……来了……了……Ծ‸Ծ 其实,客观点来说,我是半推半就从了它的。25、...
    好运不遮楼阅读 415评论 4 1
  • 撕破了脸 撕破了皮 放下所有在意 你是怎样的你? 放下了自尊 放下了委屈 抛弃所有的得意 你该怎样呼吸? 你惧怕未...
    莉莉安的斑马阅读 212评论 15 4
  • 从幼稚到懵懂 从懵懂到成熟 这一路的颠簸是你们陪伴着走过 经历这三个春秋 酸甜苦辣咸都在 谁说回忆只能长久 冰封沉...
    梦儿渺渺阅读 165评论 0 6