开发杂谈iOS网络技术iOS酷玩技术分享

网络封装处理(一)使用GCD同步网络请求

2016-11-27  本文已影响300人  冲破茧缚

现实开发中,经常会遇到这样的需求,一个页面需要批量发送几个网络请求,并且对这几个网络请求进行统一处理。这种情况直接用AFNetworking实现不了,需要对其进行进一步的封装。

实现思路:

  1. 把要批量发送的请求放入一个数组,遍历数组,依次发送请求,定义一个已完成的请求数量计数器,每个请求完成是对该计数器加一,然后判断计数器是否和请求数组的请求个数一致,如果一致则代表请求完成。
  2. 跟第一个方法相似,只是判断请求完成的方法不同,使用GCD的信号量dispatch_semaphore,配合dispatch_group来实现。

下面来具体的讲述以上两种方法:

1. 通过请求计数器来判断 :

猿题库开源的网络库框架YTKNetwork里面处理批量请求就是用这种方法,它有一个类YTKBatchReques,就是用来实现批量请求的,它实现了一个方法requestFinished,该方法对已完成的请求数量_finishedCount进行自增,然后判断其是否与请求数组_requestArray中的请求个数相等,若相等则执行一系列批量请求完成的操作。

- (void)requestFinished:(YTKRequest *)request {
    _finishedCount++;
    if (_finishedCount == _requestArray.count) {
        [self toggleAccessoriesWillStopCallBack];
        if ([_delegate respondsToSelector:@selector(batchRequestFinished:)]) {
            [_delegate batchRequestFinished:self];
        }
        if (_successCompletionBlock) {
            _successCompletionBlock(self);
        }
        [self clearCompletionBlock];
        [self toggleAccessoriesDidStopCallBack];
        [[YTKBatchRequestAgent sharedInstance] removeBatchRequest:self];
    }
}

2. GCD信号量dispatch_semaphore:

首先了解下信号量的几个方法
 1.dispatch_semaphore_create(long value);
   创建信号量,传入的value值要大于等于0,返回一个信号量
 2.dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
   如果信号量的value值大于0,则会往下执行并将value的值减1,否则,阻碍当前线程并等待timeout后再往下执行。如果等待的期间desema的值被dispatch_semaphore_signal函数加1了,且该函数所处线程获得了信号量,那么就继续向下执行并将信号量减1。如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程会自动往下执行。
 3.dispatch_semaphore_signal(dispatch_semaphore_t dsema);
   返回值为long类型,当返回值为0时表示当前并没有线程等待其处理的信号量,其处理的信号量的值加1即可。当返回值不为0时,表示其当前有(一个或多个)线程等待其处理的信号量,并且该函数唤醒了一个等待的线程(当线程有优先级时,唤醒优先级最高的线程;否则随机唤醒)。
实现过程:
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
    // 创建信号量
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
     NSURLSessionDataTask *task = [manager GET:service.url parameters:service.parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 如果请求成功,增加信号量值
        dispatch_semaphore_signal(semaphore);
         // 成功回调 主线程执行
         dispatch_async(dispatch_get_main_queue(), ^{
               !service.requestComplete?:service.requestComplete(responseObject,nil);
           });
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
             // 如果请求失败,增加信号量值
             dispatch_semaphore_signal(semaphore);
        }];
                    
     // 在网络请求任务成功之前,信号量等待中
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
 });

  dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 所有请求完成时回调
  });
参考链接

http://www.cnblogs.com/snailHL/p/3906112.html
https://github.com/yuantiku/YTKNetwork

上一篇下一篇

猜你喜欢

热点阅读