Model里面有ABCD四个属性,这4个属性每个都不能直接用,都需要去调一个Block返回回来才能用,然后界面上的textview的值需要这4个属性来拼接,每个属性都有可能为空,最后拼出来的东西还不能打乱顺序。
看了一天的JavaScript基础语法,然后水了一下群,发现一个朋友在问这样的问题:
简单分析了一下,跟iOS一道面试题一样一样的
如果一个页面需要发送4个网络请求,如何监听到所有的请求都已经回调之后再刷新UI?
自己也曾经被问到过两次,当时都是说的声明一个全局变量在收到回调的时候+1,当这个变量等于4的时候再刷新UI。
现在看起来,这样的答案确实low得可怜。其实我是知道有dispatch group 这个东西的,但是,考虑到网络请求都是异步请求并且通过block回调的,那么block里面的内容无论有没有执行完毕,group notify 总是能够在真正受到回调才会刷新数据。
看到了朋友这样的问题,在群里简单的提了我用group的解决方案之后,主动提出了我写一个demo出来的建议,然后我就开始了
temp one
首先我模拟了4个任务分别延时了0.3 0.5 0.1 和马上返回; 然后是通过block回调通知接下来的操作
|
|
由于我要模拟的是在后台的情况下执行请求任务,所以我果断的讲dispatch中的dispatch_get_main_queue
改成了 dispatch_queue_create(0, 0)
然后我写了这样的代码
|
|
我以为这个问题就解决了,然后我很自信的运行了一下
|
|
很显然我弄错了;
仔细阅读了一下代码和输出的值之后我意识到了,block回调是在notify之后执行的
temp two
然后我看了下意思的输入了disoatch_group。
等等disoatch_group_enter
disoatch_group_wait
disoatch_group_leave
这三个东西是什么鬼?
然后简单百度了一下,然后我就改了一下代码
|
|
再运行一下
|
|
搞定!
temp three
最开始我在四个任务方法里面的dispatch_after
都是Xcode 代码自动补全出来的,参数都是dispatch_get_main_queue()
,在第一次尝试的时候输出并没有什么不一样。
但是在第二次尝试的时候输出变成了
|
|
我想到了这应该是死锁造成的,因为在四个模拟任务中出了第四个dispatch_after
都将回调放到主线程去了,而
|
|
也是在主线程wait的,考虑到UI的任务都是在主线程中执行的所以我在demo中引入了一个tableview,果然,wait的时候tableview也是卡死的,所以,呵呵。折腾了半天,还是没有找到合适的办法,我决定再深入的看一下文档;
然后我看了一下
这本书
看到了这句话
所以我将调用request的方法改了一下:
|
|
问题完美解决。
temp four
后来我又想了一下,查了一下相关资料,写下了一下代码,然后发现这样也是可以的。
|
|
所以我大胆的得出了如果在block情况下使用dispatch_grop
是需要在开始人物的时候enter
并且在结束任务的时候leave
这样的话使用dispatch_notify
也是能够达到同样的效果的。
temp five
查阅了猿题库YTKNetwork相关代码之后,看到了YTKBatchRequest
这个类,他的init
方法
|
|
并且这个类有一个property finishedCount
|
|
而且这个property出了在initWithRequestArray
中进行了原始赋值以外只在
这个方法里面使用到了。
大概猜到了YTKNetwork在处理批量网络请求的时候,应该是先调用initWithRequestArray
这个初始化方法,把所有网络请求的实例放进去,然后再调用
|
|
这个方法开始举行网络请求,最后通过finishedCount
这个熟悉来进行回调,如果有某一个失败了,那最后就返回失败巴拉巴拉…
这段写的有点水,主要是没有十分仔细的去阅读YTKNetwork的源码。大概看了一下,YTKNetwork的处理思路跟我之前的思路有些不谋而合,也是通过添加一个flag值来判断回调是否全部收到。不过经过猿题库团队的封装之后,这种问题的处理方式就变得更加的优雅了。
由于我demo只是写了几个简单的方法来模拟这种应用场景,所以我也简单的用YTK的思路来进行一下模拟
|
|
结果是:
|
|
好了第三种思路完成。
temp six
然后我又看到资料说GCD的信号量也能实现这种需求,看了一下相关资料,然后我是这写了这段代码
|
|
很不幸:
|
|
over是没有打印出来的,具体原因,我等我再仔细查找查找吧!
结语
没有结语,不知道具体实践中有没有其他更好的办法。如果有,也可以给我留言,我们一起讨论。