美文网首页iOS面试题+基础知识
iOS开发 GCD信号量实现AFNetworking的顺序请求

iOS开发 GCD信号量实现AFNetworking的顺序请求

作者: 叩首问路梦码为生 | 来源:发表于2018-12-20 10:55 被阅读19次

[图片上传失败...(image-97ada5-1545274514848)]

最近遇到一个☝️问题。一个页面有多个接口,需要请求完接口后,在把接口数据组装排序后再展示。于是我第一反应是使用GCD_group或者barrier.经过实践失败了。最后经过多方调研,使用dispatch_semaphore解决了这个问题,但是也有遇到坑。。。

首先贴出解决方案
#1

   //    /创建信号量为0
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, queue, ^{
        [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/journalismApi" param:nil success:^(id data) {
//            信号量📶+1
            dispatch_semaphore_signal(semaphore);
            NSLog(@"1请求成功");
        } failure:^(NSInteger resultId, NSString *errorMsg) {
//            信号量📶+1
            dispatch_semaphore_signal(semaphore);
        }];  
    });

    dispatch_group_async(group, queue, ^{
        [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinApi?type=1&page=1" param:nil success:^(id data) {
            //            信号量📶+1
            dispatch_semaphore_signal(semaphore);
            NSLog(@"2请求成功");
        } failure:^(NSInteger resultId, NSString *errorMsg) {
            //            信号量📶+1
            dispatch_semaphore_signal(semaphore);
        }];
    });

    dispatch_group_notify(group, queue, ^{
//        信号量 -1 为0时wait会阻塞线程
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"信号量为0");
        [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinCommentApi?id=27610708&page=1" param:nil success:^(id data) {
            NSLog(@"3请求成功");
        } failure:^(NSInteger resultId, NSString *errorMsg) {
        }];
    });

打印结果1或2请求结束后才会请求3

2018-09-03 21:49:47.309334+0800 信号量[20350:707280] 2请求成功
2018-09-03 21:49:48.299139+0800 信号量[20350:707280] 1请求成功
2018-09-03 21:49:48.299139+0800 信号量[20350:707371] 信号量为0
2018-09-03 21:49:48.640118+0800 信号量[20350:707280] 3请求成功

#2

  dispatch_queue_t queue = dispatch_queue_create("ben", NULL);
    dispatch_async(queue, ^{
         NSLog(@"current1:%@",[NSThread currentThread]);
        dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);
        [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/journalismApi" param:nil success:^(id data) {
            dispatch_semaphore_signal(semaphore);
            NSLog(@"1请求成功");
        } failure:^(NSInteger resultId, NSString *errorMsg) {
            dispatch_semaphore_signal(semaphore);
        }];

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1

        [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinApi?type=1&page=1" param:nil success:^(id data) {
            dispatch_semaphore_signal(semaphore);
            NSLog(@"2请求成功");

        } failure:^(NSInteger resultId, NSString *errorMsg) {
            dispatch_semaphore_signal(semaphore);
        }];
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1

        [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinCommentApi?id=27610708&page=1" param:nil success:^(id data) {
            NSLog(@"3请求成功");
        } failure:^(NSInteger resultId, NSString *errorMsg) {

        }];

    });

打印结果顺序执行1,2,3

2018-09-03 21:52:34.881525+0800 信号量[20448:711755] 1请求成功
2018-09-03 21:52:35.659227+0800 信号量[20448:711755] 2请求成功
2018-09-03 21:52:35.951249+0800 信号量[20448:711755] 3请求成功

遇到的坑

 NSLog(@"current1:%@",[NSThread currentThread]);

    dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);
    [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinApi?type=1&page=1" param:nil success:^(id data) {
        dispatch_semaphore_signal(semaphore);
        NSLog(@"2请求成功");

    } failure:^(NSInteger resultId, NSString *errorMsg) {
        dispatch_semaphore_signal(semaphore);
    }];
    NSLog(@"你会来这儿吗1");
    NSLog(@"current1:%@",[NSThread currentThread]);
   //    #######阻塞了主线程
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1

    NSLog(@"你会来这儿吗2");
    [ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinCommentApi?id=27610708&page=1" param:nil success:^(id data) {

        NSLog(@"3请求成功");

    } failure:^(NSInteger resultId, NSString *errorMsg) {

    }];

打印你会发现卡在了NSLog(@"你会来这儿吗1"); 这里
原因:阻塞了主线程。

2018-09-03 21:56:36.863662+0800 信号量[20583:717991] current1:<NSThread: 0x604000076680>{number = 1, name = main}
2018-09-03 21:56:36.961266+0800 信号量[20583:717991] 你会来这儿吗1
2018-09-03 21:56:36.961413+0800 信号量[20583:717991] current1:<NSThread: 0x604000076680>{number = 1, name = main}

参考博客iOS开发 多线程的高级应用(一)

demo传送门:GitHub

作者:本本的开心牧场
链接:https://www.jianshu.com/p/72843289ad5d
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

相关文章

网友评论

    本文标题:iOS开发 GCD信号量实现AFNetworking的顺序请求

    本文链接:https://www.haomeiwen.com/subject/smaekqtx.html