美文网首页iOS DeveloperiOS大咖
iOS 多个网络请求结束后通知执行方法 参考rac_liftSe

iOS 多个网络请求结束后通知执行方法 参考rac_liftSe

作者: Poison_19ce | 来源:发表于2018-11-12 17:22 被阅读119次

闲来无事做,不如学学习

平常项目场景中,肯定会出现这样一个场景,多个网络请求同时进行,但却要将多个网络请求的结果同时进行处理

网上的解决办法很多,我之前项目中采用的就是GCD的dispatch_group_notify来做的,但是这样有一个弊端,代码写起来杂乱,看起来很不美观,管理不方便,不容易维护

后来学习了Reactive Cocoa框架(不得不说这个框架是十分nb啊)

其中有一个是专门用来解决这个问题的,就是rac_liftSelector,有兴趣的朋友可以去网上搜一搜rac_liftSelector这个方法,就会发现真的很方便,也很强大

那既然RAC已经完美解决了这个问题,为什么我还要说一说呢,因为我们项目没用rac啊,哈哈哈

项目最开始就是按照MVC搭建,如果换MVVM+RAC 需要把整个项目重新写一遍了。。。(本人也是比较懒),所以决定,秉承着懒人原则,自己动手造一个轮子

先说明RAC处理办法:

RAC 在NSObject的一个信号Category中写了rac_liftSelector,而rac整套框架都基于一个概念,信号(RACSingle)

可以理解为,一个操作就是一个信号,未被触发的操作为冷信号,已触发的操作为热信号

未解决bugList(后面会一一解决,解决后会添加删除线):

NSObject的分类中添加KVO会导致bug,假如其他使用该方法继承NSObject的类实现了KVO的observeValueForKeyPath,会导致NSObect的分类中的observeValueForKeyPath不执行。

每一个Single的block中都需要进行[subscriber sendSingle:(nil)||(结果)]; 必须调用该sendSingle函数,否则最后的通知selector无法执行,会导致控制器无法释放

需要优化列表

getIdentifier函数优化

代码结构可以添加信号组(SingleGroup)优化

2018 - 11 - 13日更新 (下面有以前版本,但存在部分bug,最新的是修改过的)

本修改基于上一版本,如果有疑问可以参考上版本代码

首先我说明我上个版本的bug以及问题

1、代码没有rac简洁

2、SingleManager如果不强引用则会导致crash

3、若该组方法未执行完毕,又重新reload一次会导致SingleManager强引用失效,造成crash

4、即使解决了SingleManager的强引用,也会导致在多次执行通知回调触发方法结束后回调的数据错乱,很严重的问题

基于以上问题,对代码进行修改及重构

还是本着一个原则,参考RAC,抱大腿

首先忽略第一个问题,看第二个问题

SingleManager不强引用会导致crash,RAC做法:写在NSObject的分类中

写在Category中很好的解决了这个问题,为什么?因为当前对象就是控制器,控制器不释放,他就不会释放,也就不会造成野指针崩溃(之前我就忽略了这个细节,果然需要打磨)

第三个问题&&第四个问题

其实解决了第二个问题就相当于解决了第三个问题,但是他们是一个连锁反应,我需要把遇到的问题提出来,大家可以共同参考进步

而第四个问题就是我在解决了SingleManager强引用问题的同时导致的,同时调用两次,会发现,回调数据错乱,因为代码没有做数据绑定

有了以上的解决方案,那么来解决一下,代码变动较大,直接从头捋清思路

创建 NSObject+Single的Category、创建Single的Class、创建Subscriber的Protocol、创建WaitSingle的Class(处理数据信号绑定)

首先创建Subscriber的Protocol ,为其添加方法 - (void)sendSingle:(id)result;

此处需要有一个修改 将 NS_ASSUME_NONNULL_BEGIN 与NS_ASSUME_NONNULL_END 删除,否则在该方法传入nil的时候有一个黄色警告,比较烦

Subscriber protocol

然后我们来看一下Single类中的修改

我们首先把之前SingleManager中的创建信号任务的方法转移到Single中,并且修改了一下命名,以及添加了Single的标示符号

以下是.h 和 .m

Single.h Single.m


可以看到,只把之前的SingleManager中创建信号方法转移到了Single中,实现没有改变

接下来就是最重要的了

将SingleManager中的触发方法放入NSObject+Single中

并且创建WaitSingle用来做数据绑定模型类

将SingleManager.m中的属性全都转移到该类

其次提供方法为Single创建组合标示identifier

然后修改报错部分代码进行替换,以下是实现

NSObject+Single.m NSObject+Single.m NSObject+Single.m

这样我们就完成了对代码的修改,以下是代码的使用方式

实现方式

2018 - 11 - 12 日初稿

基于该rac原理,对信号进行思考,无非就是多个请求结束后,触发某个操作

首先想到的是什么,KVO啊,每一个操作都为一个信号,我想要监听其改变,那么我利用KVO进行观察就OK啦

其次思考,rac中利用sendNext来处理结果,那么我也提供一个函数方法来处理结果

然后开始动手

首先创建2个类: Single 、 SingleManager

Single主要就是作为一个信号,而SingleManager就是用来管理信号的

既然SingleManager是用来管理信号的,那么好,我需要向singleManager添加任务(一次网络请求,或者是一些代码等被我统称为任务 task),其次,我需要提供多个方法执行结束后所触发的方法(其实就好像一个UIButton  对其addTarget,只不过换了一个形式)

那么Single类是用来操作信号的,所以我需要对Single类添加存储外界传入的task,以及提供一个id 类型的result来调用以及一个方法 发送信号,将冷信号设置为热信号

下面是我的Single.h定义

下面是我的SingleManager.h的定义

SingleManager.h

这里我采用block的方式进行添加任务

使用- (LXSingle*)singleAddTask:(void(^)(LXSingle*lx_single))task;来进行定义任务

使用 - (void)singleWithSelector:(NSArray<LXSingle *> *)array target:(id)target notificationSelector:(SEL)selector;来触发任务

使用代码如下

ViewController.m中的调用方式

注意:singleManager一定要使用全局变量进行强引用,否则Single中sendSingle会因为局部变量的释放而导致Crash

-----------------分割线(以上是初稿)--------------

最后说一句,喜欢的话给个小红心,有问题可以评论提问

爱你们呦 尊重原创,转载请著名作者以及简书地址

https://www.jianshu.com/writer#/notebooks/11755935/notes/36638571

相关文章

网友评论

    本文标题:iOS 多个网络请求结束后通知执行方法 参考rac_liftSe

    本文链接:https://www.haomeiwen.com/subject/gxpcfqtx.html