RAC中常见的高级用法-组合
阅读原文时间:2023年07月11日阅读:3
  • 组合:

concat组合:

          按一定顺序执行皇上与皇太子关系

concat底层实现:

    1.当拼接信号被订阅,就会调用拼接信号的didSubscribe

    2.didSubscribe中会先订阅第一个源信号(signalA)

    3.会执行第一个源信号(signalA)的didSubscribe
    4.第一个源信号(signalA)didSubscribe中发送值,就会调用第一个源信号(signalA)订阅者的nextBlock,通过拼接信号的订阅者把值发送出来.
    5.第一个源信号(signalA)didSubscribe中发送完成,就会调用第一个源信号(signalA)订阅者的completedBlock,订阅第二个源信号(signalB)这时候才激活(signalB)。
    6.订阅第二个源信号(signalB),执行第二个源信号(signalB)的didSubscribe

    7.第二个源信号(signalA)didSubscribe中发送值,就会通过拼接信号的订阅者把值发送出来.

- (void)concat
{
//创建信号A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
//发送请求
NSLog(@"发送上部分的请求");
//发送信号
[subscriber sendNext:@"上部分数据"];
//发送完毕
//加上后就可以上部分发送完毕后发送下半部分信号
[subscriber sendCompleted];
return nil;
}];

//创建信号B  
RACSignal \*signalB = \[RACSignal createSignal:^RACDisposable \*(id<RACSubscriber> subscriber) {  
    //发送请求  
    NSLog(@"发送下部分的请求");  
    //发送信号  
    \[subscriber sendNext:@"下部分数据"\];  
    return nil;  
}\];  
//创建组合信号  
//concat:按顺序去连接(组合)  
//注意:第一个信号必须调用sendCompleted  
RACSignal \*concat = \[signalA concat:signalB\];  
//订阅组合信号  
\[concat subscribeNext:^(id x) {  
    //既能拿到A信号的值,又能拿到B信号的值  
    NSLog(@"%@", x);  
}\];  

}

then:

     用于连接两个信号,当第一个信号完成,才会连接then返回的信号

     注意: 使用then之前的信号的值会被忽略掉.

底层实现:
    1、先过滤掉之前的信号发出的值。

    2.使用concat连接then返回的信号

- (void)then
{
//创建信号A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
//发送请求
NSLog(@"发送上部分的请求");
//发送信号
[subscriber sendNext:@"上部分数据"];
//发送完毕
//加上后就可以上部分发送完毕后发送下半部分信号
[subscriber sendCompleted];
return nil;

}\];

//创建信号B  
RACSignal \*signalB = \[RACSignal createSignal:^RACDisposable \*(id<RACSubscriber> subscriber) {  
    //发送请求  
    NSLog(@"发送下部分的请求");  
    //发送信号  
    \[subscriber sendNext:@"下部分数据"\];  
    return nil;

}\];

//thenSignal组合信号  
//then:会忽略掉第一个信号的所有值  
RACSignal \*thenSignal = \[signalA then:^RACSignal \*{  
    //返回的信号就是需要组合的信号  
    return signalB;  
}\];  
//订阅信号  
\[thenSignal subscribeNext:^(id x) {  
    NSLog(@"%@", x);  
}\];

/\*  
 结果:  
 发送上部分的请求  
 发送下部分的请求  
 下部分数据  
 \*/  

}

merge

     把多个信号合并为一个信号,任何一个信号有新值的时候就会调用,没有顺序

- (void)merge
{
//创建信号A
RACSubject *signalA = [RACSubject subject];
//创建信号B
RACSubject *signalB = [RACSubject subject];

//组合信号  
RACSignal \*mergeSignal = \[signalA merge:signalB\];

//订阅信号  
\[mergeSignal subscribeNext:^(id x) {  
    //任意一个信号发送内容都会来到这个block  
    NSLog(@"%@", x);  
}\];

//发送数据  
\[signalB sendNext:@"下部分"\];  
\[signalA sendNext:@"上部分"\];  
/\*结果:下部分上部分\*/  

}

zipWith: 等所有信号都发送内容的时候才会调用(夫妻关系)

     把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件

底层实现:
    1.定义压缩信号,内部就会自动订阅signalA,signalB

    2.每当signalA或者signalB发出信号,就会判断signalA,signalB有没有发出个信号,有就会把最近发出的信号都包装成元组发出。

- (void)zipWith
{
//创建信号A
RACSubject *signalA = [RACSubject subject];
//创建信号B
RACSubject *signalB = [RACSubject subject];
//压缩成一个信号
//当一个界面多个请求时,要等所有的请求都完成才能更新UI
//打印顺序跟组合顺序有关,跟发送顺序无关
RACSignal *zipSignal = [signalA zipWith:signalB];
//订阅信号
[zipSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
//发送信号
[signalA sendNext:@"HMJ"];
[signalB sendNext:@"GQ"];
/*
结果

(
HMJ,
GQ
)
*/
}

combineLatest:

     将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。

底层实现:
    1.当组合信号被订阅,内部会自动订阅signalA,signalB,必须两个信号都发出内容,才会被触发。

    2.并且把两个信号组合成元组发出。

- (void)combineLatest
{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
[subscriber sendNext:@"A"];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id subscriber) {
[subscriber sendNext:@"B"];
return nil;
}];
//把两个信号组合成一个信号
RACSignal *combineSignal = [signalA combineLatestWith:signalB];
//订阅组合信号
[combineSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
}

reduce聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值

     常见的用法(先组合在聚合)。combineLatest:(id)signals reduce:(id (^)())reduceBlock

reduce中的block简介:
    reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
    reduceblcok的返回值:聚合信号之后的内容。

底层实现:

    订阅聚合信号,每次有内容发出,就会执行reduceblcok,把信号内容转换成reduceblcok返回的值。

- (void)combineLatestWithReduce
{
/*登录界面:两个文本框(账户,密码) + 一个登录按钮*/

//组合多个信号  
//reduce:聚合  
//reduceBlock的参数与组合的信号一一对应,可以在reduce:后拿到信号的值  
RACSignal \*combineSignal = \[RACSignal combineLatest:@\[\_accountName.rac\_textSignal, \_passWord.rac\_textSignal\] reduce:^id(NSString \*account, NSString \*pwd){  
    //block:只要源信号发送内容就会调用,组合成新的一个值  
    //聚合的值就是组合信号的内容  
    return @(account.length && pwd.length);  
}\];  
//订阅信号  
//    \[combineSignal subscribeNext:^(id x) {  
//        self.loginBtn.enabled = \[x boolValue\];  
//  
//    }\];  
//等同于  
RAC(self.loginBtn, enabled) = combineSignal;  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章