iOS开发中如何解决网络请求的依赖关系(同时应用于业务层)
- 比如:一个(或多个)接口的请求需要依赖于另一个(或多个)网络请求的结果?
目录
- 操作依赖 – NSOperation
- 逻辑判断 – if/else
- 线程同步 – 组队列
- 线程同步 – 阻塞任务
- 线程同步 – 信号量机制
操作依赖 – NSOperation
NSOperation 操作依赖和优先级(不适用,异步网络请求并不是立刻返回,无法保证回调时再开启下一个网络请求)
1 | // Do any additional setup after loading the view, typically from a nib. |
逻辑判断 – if/else
上一个网络请求的响应回调后,下一网络请求的才开始执行
1 | NSString *urlString = @"http://www.icocos.cn"; |
但是这样会存在一个概率性的问题,就会有可能根本拿不到结果,或者由于网络慢和用户操作之间的关系导致不可预料的问题。
线程同步 – 组队列(dispatch_group)
dispatch_group是GCD(Grand Central Dispatch)中的一组方法,他有一个组的概念,可以把相关的任务归并到一个组内来执行,通过监听组内所有任务的执行情况来做相应处理。
- 1.dispatch_group_async
- 将代码块dispatch_block_t block放入队列dispatch_queue_t queue中执行;并和调度组dispatch_group_t group相互关联;如果提交到dispatch_queue_t queue中的block全都执行完毕会调用dispatch_group_notify并且dispatch_group_wait会停止等待;
- 2.dispatch_group_enter(group)、dispatch_group_leave(group)
- 和内存管理的引用计数类似,我们可以认为group也持有一个整形变量(只是假设),当调用enter时计数加1,调用leave时计数减1,当计数为0时会调用dispatch_group_notify并且dispatch_group_wait会停止等待;
- 3.dispatch_group_notify
- 当关联到dispatch_group_t上的dispatch_group_async任务执行完毕或者是关联在上面的dispatch_group_enter、dispatch_group_leave成对出现了。参数中的dispatch_block_t block会被提交到dispatch_queue_t queue中执行。
- 4.dispatch_group_wait
- 和dispatch_group_notify功能类似(多了一个dispatch_time_t参数可以设置超时时间),在group上任务完成前,dispatch_group_wait会阻塞当前线程(所以不能放在主线程调用)一直等待;当group上任务完成,或者等待时间超过设置的超时时间会结束等待;
- 5………..
1 | bashdispatch_queue_t dispatchQueue = dispatch_queue_create("icocos.queue.next", DISPATCH_QUEUE_CONCURRENT); |
线程同步 –阻塞任务(dispatch_barrier):
一个dispatch barrier 允许在一个并发队列中创建一个同步点。当在并发队列中遇到一个barrier, 他会延迟执行barrier的block,等待所有在barrier之前提交的blocks执行结束。 这时,barrier block自己开始执行。 之后, 队列继续正常的执行操作。
调用这个函数总是在barrier block被提交之后立即返回,不会等到block被执行。当barrier block到并发队列的最前端,他不会立即执行。相反,队列会等到所有当前正在执行的blocks结束执行。到这时,barrier才开始自己执行。所有在barrier block之后提交的blocks会等到barrier block结束之后才执行。
- dispatch_barrier_async函数的作用
- 1.实现高效率的数据库访问和文件访问
- 2.避免数据竞争
1 | /* 创建并发队列 */ |
线程同步 – 信号量机制(dispatch_semaphore):
- 信号量:
- 就是一种可用来控制访问资源的数量的标识,设定了一个信号量,在线程访问之前,加上信号量的处理,则可告知系统按照我们指定的信号量数量来执行多个线程。
其实,这有点类似锁机制了,只不过信号量都是系统帮助我们处理了,我们只需要在执行线程之前,设定一个信号量值,并且在使用时,加上信号量处理方法就行了。
信号量主要有3个函数
创建信号量,参数:信号量的初值,如果小于0则会返回NULL
dispatch_semaphore_create(信号量值)
//等待降低信号量
dispatch_semaphore_wait(信号量,等待时间)
//提高信号量
dispatch_semaphore_signal(信号量)
注意,正常的使用顺序是先降低然后再提高,这两个函数通常成对使用。
1 | - (void)getToken |