美文网首页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