文章系列
《RACSignal 》
《RACDisposable》
《RACSubject、RACReplaySubject》
《iOS RAC - 基本用法》
《iOS RAC - 定时器》
《iOS RAC - RACMulticastConnection》
《iOS RAC - RACCommand》
《iOS RAC - 核心方法bind》
《iOS RAC - 集合RACTuple、RACSequence》
《iOS RAC - rac_leftSelector》
《iOS RAC - 映射》
《iOS RAC - 过滤》
《iOS RAC - 登录页面,MVVM》
在RAC中我们会看到bind,了解一下如何使用吧
1、创建信号
RACSubject * subject = [RACSubject subject];
2、绑定信号
[subject bind:^RACSignalBindBlock _Nonnull{
}];
- 不知道返回值是啥,点进去看看
typedef RACSignal * _Nullable (^RACSignalBindBlock)(ValueType _Nullable value, BOOL *stop);
看完之后知道了,他的返回是要是一个信号,并且带两个参数:一个value
,一个bool
[subject bind:^RACSignalBindBlock _Nonnull{
return ^RACSignal *(id _Nullable value, BOOL *stop){
return [[RACSignal alloc] init];
};
}];
现在我们已经绑定啦,然后我们愉快的运行吧,成功运行完成,一切都是那么风平浪静,接下来要发送信息了。
[subject sendNext:@"启动自毁程序"];
现在问题来了,我们都发送数据了,在哪里接收啊????
bind
方法中返回的就是signal
,既然是信号,那么就订阅。
RACSignal * signal = [subject bind:^RACSignalBindBlock _Nonnull{
return ^RACSignal *(id _Nullable value, BOOL *stop){
return [[RACSignal alloc] init];
};
}];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"收到的数据 - %@",x);
}];
在愉快的运行……不对,不愉快啊,程序挂掉了。
为什么呢?
因为我们用原始信号(subject)发送了数据,但是返回的这个信号里面并没有这个数据return [[RACSignal alloc] init]
,所以就挂掉啦。
既然这样子,我们把数据返回就OK啦
这个操作比较骚因为默认是没有导入头文件的,所以我们先要导入头文件#import "RACReturnSignal.h"
然后把return [[RACSignal alloc] init]
替换为return [RACReturnSignal return:value]
这样子就可以啦,至于为什么返回value
,这个就简单啦,通过我们发送的数据是字符串,一个对象,总不可能用一个bool去表示吧,
所以value就是我们发送的数据,如果不需要进行处理,直接返回value就ok了。
现在我们已经在应用层使用了bind,但是感觉并没有什么卵用,其实有一种应用场景,就是字典转模型,现在先去看看底层是如何实现的吧
底层实现
1、RACSubject * subject = [RACSubject subject];
这个可以参照iOS RAC - RACSubject、RACReplaySubject这个文章,这里不做介绍了
2、bind这个方法有点长,慢慢看
从上面的图中可以看出,block不能为NULL
然后下面接着就是返回一个信号并且把block保存了起来
所以我们在订阅信号之后调用的block就是这个block
在保存block之后又定义了两个block分别是:completeSignal
和addSignal
接下来
红色部分订阅,绿色部分的时候就把发送的数据x
在bindingblock中调用,所以这里的x就是对应外面的value。
所以在外面执行sendnext 方法之后就会调用bindingBlock,就会返回信号,在去调用subscribeNext
简单点说就是在我们发送数据的时候,才会回来执行我们bind里面的信号的block,执行了bind方法里面的信号的block,才会去调用信号的subscribeNext
方法