首页 > 系统 > iOS > 正文

iOS 依次执行 异步网络请求的一种实现

2019-11-08 00:05:30
字体:
来源:转载
供稿:网友

1.首先先介绍一个概念dispatch_semaphore


dispatch_semaphore信号量为基于计数器的一种多线程同步机制。用于解决在多个线程访问共有资源时候,会因为多线程的特性而引发数据出错的问题.如果semaphore计数大于等于1,计数-1,返回,程序继续运行。如果计数为0,则等待。dispatch_semaphore_signal(semaphore)为计数+1操作。dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)为设置等待时间,这里设置的等待时间是一直等待。我们可以通俗的理解为单柜台排队点餐,计数默认为0,每当有顾客点餐,计数+1,点餐结束-1归零继续等待下一位顾客。比较类似于NSLock。

2.主要是介绍使用dispatch_semaphore和NSOperationQueue结合实现依次执行异步请求


NSOperationQueue中装有任务,设置任务之间相互依赖NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ [self request:@”A”]; }];NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ [self request:@"B"];}];NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ [self request:@”C”]; }];[operation2 addDependency:operation1]; //任务二依赖任务一 [operation3 addDependency:operation2]; //任务三依赖任务二将任务加入队列中NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO]; 测试执行顺序并非是按照A-B-C依赖执行,并且无法得知何时任务执行完毕,进行下一步操作.下面解决这两个问题

3.解决如何依次执行.就要用到开头介绍的:dispatch_semaphore来限制是否执行

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); //默认创建的信号为0[[NetworkManager shared] RequestWithMethod:HttpMethod_POST Url:strURL params:params success:^(NSURLsessionDataTask *task, id responSEObject) { NSLog(@"%@",index); dispatch_semaphore_signal(semaphore); //这里请求成功信号量 +1 为1} failure:^(NSURLSessionDataTask *task, NSError *error) { dispatch_semaphore_signal(semaphore); //这里请求失败信号量 +1 为1}];dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //走到这里如果信号量为0 则不再执行下面的代码 一直等待 信号量不是0 出现 才会执行下面代码,然后信号量为 - 1这个解决了依次执行的问题 下面解决怎么知道全部执行完毕呢

4. 执行完毕问题的解决,使用KVO监听任务数是否为0

//添加监听 监听队列是否全部执行完毕[queue addObserver:self forKeyPath:@"operationCount" options:0 context:nil];-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {if ([keyPath isEqualToString:@"operationCount"]) { NSOperationQueue *queue = (NSOperationQueue *)object; if (queue.operationCount == 0) { NSLog(@"全部完成"); }}}

5.至此解决了依次执行异步网络请求 的一种实现方法


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表