1、ReactiveCocoa中的类
1、在RAC中最核心的类是RACSignal。RACSiganl是信号类,一般表示将来有数据传递,只有有数据改变,信号内部接收到数据,就会马上发出数据
- 信号类(RACSiganl)只是表示当数据改变时,信号内部发出数据,他本身更不具备发送信号的能力,而是交给内部一个订阅者去发出
- 默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变成热信号,值改变了才会触发
- 如何订阅信号:调用信号RACSignal的subscribeNext就能订阅
//1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
//block调用时刻:每当有订阅者订阅信号,就会电泳block
//2.发出信号
[subscriber sendNext:@1];
//如果不发送数据,最好发送信号完成,内部会自动调用[RACDisposable disposable]取消订阅信号
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
//block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信息
//执行完block后,当前信号就不会被订阅了。
NSLog(@"信号被销毁");
}];
}];
//3.订阅信号,才会激活信号
[signal subscribeNext:^(id x) {
NSLog(@"接收到数据%@",x);
}];
2、RACTuple:元组类,类似于NSArray。用来包装值
RACSequence:RAC中的集合类,用于替代NSArray,NSDictionary,可以使用它来快速遍历数组合字典
//1.遍历数组
NSArray *numbers = @[@1,@2,@3,@4,@5];
/*
这里有三个步骤
第一步:把数组转换成几个RACSequence numbers.rac_sequence
第二步:把集合RACSequence转换RACSignal信号类,numbers.rac_sequence.signal
第三步:订阅号,激活信号,会自动把集合中的所有值遍历出来
*/
[numbers.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
//2.遍历字典
NSDictionary *dict = @{@"name":@"xiaoming",@"age":@"15",@"sex":@"男",@"phone":@"18275317977"};
[dict.rac_sequence.signal subscribeNext:^(id x) {
//解包元组,会把元组的值,按顺序给参数里面的变量赋值
RACTupleUnpack(NSString *key,NSString *value) = x;
//类似于
//NSString *key = x[0];
//NSString *value = x[1];
NSLog(@"key:%@ \t value:%@",key,value);
}];
3.RACCommand类是RAC中用于处理事件的类,可以把时间如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程,常用于监听按钮点击,网络请求
//1.创建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"执行命令");
//signalBlock中必须返回一个信号,不能穿nil,如果不想传递信号,直接返回一个空信号
//return [RACSignal empty];
//2.创建信号,用来传递数据
return [RACSignal createSignal:^RACDisposable *(id subscriber) {
[subscriber sendNext:@"请求数据"];
//注意:数据传递完,最好调用sendCompleted,这是命令才执行完成
[subscriber sendCompleted];
return nil;
}];
}];
//2.强引用命令,不要被销毁,否则接收不到数据
_command = command;
//3.订阅RACCommend中的信号
// [command.executionSignals subscribeNext:^(id x) {
// [x subscribeNext:^(id x) {
// NSLog(@"%@",x);
// }];
// }];
//RAC高级用法
//switchToLatest:用于signal of signals,获取signal of signals 发出的最新信号。也就是可以直接那袋RACCommand的信号了
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
//4.监听命令是否执行完毕,默认会再来一次,可以直接跳过,skip表示跳过第一次信号
[[command.executing skip:1] subscribeNext:^(id x) {
if ([x boolValue]) {
//正在执行
NSLog(@"正在执行");
} else {
//执行完成
NSLog(@"执行完成");
}
}];
//5.执行命令
[self.command execute:@1];
4.RACMulticastConnection用于当一个信号被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。
- RACMulticastConnection通过RACSignal的-publish或者-muticast方法创建
//1.创建请求信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
NSLog(@"发出请求");
return nil;
}];
//2.订阅信号1
[signal subscribeNext:^(id x) {
NSLog(@"接收数据");
}];
//2.订阅信号2
[signal subscribeNext:^(id x) {
NSLog(@"接收数据");
}];
//3.�运行结果,会执行两次发送请求,也就是每次订阅都会发送一次请求
2017-02-08 11:23:00.883 ReactiveCocoaDemo[1045:36247] 发出请求
2017-02-08 11:23:00.884 ReactiveCocoaDemo[1045:36247] 发出请求
//RACMulticastConnection解决请求重复问题
//1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
NSLog(@"发出请求");
[subscriber sendNext:@1];
return nil;
}];
//2.创建链接
RACMulticastConnection *connection = [signal publish];
//3.订阅信号
//注意:订阅型号也不能激活信号,只是保存订阅者到数组,当调用链接,就会一次性调用所有订阅者的sendNext:
[connection.signal subscribeNext:^(id x) {
NSLog(@"订阅者一信号 %@",x);
}];
[connection.signal subscribeNext:^(id x) {
NSLog(@"订阅者二信号 %@",x);
}];
//4.链接,激活信号
[connection connect];
2、ReactiveCocoa开发中常见用法
1.替代代理
- rac_signalFirSelector:用于替代代理
2、替代kvo - rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变
3、监听事件 - rac_signalForControlEvents:用于监听某个事件
4、代替通知 - rac_addObsererForName:用于监听某个通知
5、监听文本框文字改变 - rac_textSignal:只要文本框发出改变就会发出这个信号。
6、处理当界面又多次请求时,需要都获取到数据时,才能展示界面 - rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就回去出发第一个selector参数的方法
- 使用注意:几个信号,参数一的方法就是几个参数,每个参数对应信号发出的数据
3、ReactiveCocoa常见的宏
1、RAC(TARGET, [KEYPATH, [NIL_VALUE]])
用于给某个对象的某个属性绑定
//只要修改文本框文字,就会修改label的文字
RAC(self.titleLable,text) = _textField.rac_textSignal;
2、RACObserve(self, name)
监听某个对象的某个属性,返回的是信号
[RACObserve(self.view, center) subscribeNext:^(id x) {
NSLog(@"%@",x);
}
3、@weakify(Obj)
和@strongify(Obj)
,一般两个都是配套使用,在猪头文件(ReactiveCocoa.h)中并没有导入,余姚自己手动导入,RACEXTScope.h才可以使用。但是每次导入都非常麻烦,只需要在主头文件自己导入就好了
4、RACTuplePack()
把数据包装成RACTuple(元组类)
//把参数中的数据包装成元组
RACTuple *tuple = RACTuplePack(@10,@30);
5、RACTupleUnpack()
吧RACTuple解包成对应的数据
//把参数中的数据包装成元组
RACTuple *tuple = RACTuplePack(@10,@30);
RACTupleUnpack(NSNumber *one,NSNumber *two) = tuple;