前言
自己百度看了几篇ReactiveObjc的使用文章,随后自己创建一个Demo跟着敲了一波.看懂不如手动跟着敲一遍,至少增强了自己的记忆力。不喜勿喷。……
RACSignal
默认是冷信号,只有订阅了这个信号才会会变为热信号
//创建信号
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"Hello word"];
[subscriber sendCompleted]; // 如果不在发送数据,最好发送信号完成,内部会自动调用[RACDisposable disposable]取消订阅信号
return [RACDisposable disposableWithBlock:^{
//block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号
// 执行完Block后,当前信号就不在被订阅了。
NSLog(@"销毁了");
}];
}];
//订阅信号
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"接收到了 %@",x);
}];
//输出:接收到了 Hello word
//销毁了
RACDisposable
RACDisposable * disposable = [signal subscribeNext:^(id _Nullable x) {
NSLog(@"接收到了 %@",x);
}];
[disposable dispose];
RACSubject
RACSubject:信号提供者,自己可以充当信号,又能发送信号.通常用来代替代理
使用方法
1.创建信号 [RACSubject subject],跟RACSiganl不一样,创建信号时没有block。
2.订阅信号 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
3.发送信号 sendNext:(id)value
RACSubject * subject = [RACSubject subject];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"1.接收到了%@",x);
}];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"2.接收到了%@",x);
}];
[subject sendNext:@"hello word"];
[subject sendCompleted];
//输出: 1.接收到了hello word
//2.接收到了hello word
RACReplaySubject
遍历保存的所有值,一个一个调用订阅者的nextBlock
RACReplaySubject * replaySub = [RACReplaySubject subject];
[replaySub sendNext:@"hello"];
[replaySub sendNext:@"kitty"];
[replaySub subscribeNext:^(id _Nullable x) {
NSLog(@"1.接收到了%@",x);
}];
[replaySub subscribeNext:^(id _Nullable x) {
NSLog(@"2.接收到了%@",x);
}];
/*
输出:1.接收到了hello
1.接收到了kitty
2.接收到了hello
2.接收到了kitty
*/
RACMulticastConnection
RACMulticastConnection是为了解决多次调用创建信号的Block。
//创建信号
NSLog(@"=============================");
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"发送请求");
[subscriber sendNext:@"1"];
return [RACDisposable disposableWithBlock:^{
NSLog(@"销毁了");
}];
}];
RACMulticastConnection * connect = [signal publish];
[connect.signal subscribeNext:^(id _Nullable x) {
NSLog(@"1.接收到了%@",x);
}];
[connect.signal subscribeNext:^(id _Nullable x) {
NSLog(@"2.接收到了%@",x);
}];
[connect connect];
RACCommand
这块理解有点模糊,智商不够
RACCommand * command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"执行命令");
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"请求数据"];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"数据销毁");
}];
}];
}];
_command = command;
[command.executing subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]== YES) {
NSLog(@"当前正在执行,%@",x);
}else{
NSLog(@"执行完成,%@",x);
}
}];
[self.command execute:@1];
记录的函数
combineLatest
/*
此代码是将combineLatest:后面的数组中的信合打包成为一个新的信号。只有当两个信号都成功发送过信号的时候打包后的信号才能正常执行订阅后的代码块。
*/
RACSubject * one = [RACSubject subject];
RACSubject * two = [RACSubject subject];
[[RACSignal combineLatest:@[one,two]] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@"信号发送combineLatest");
}];
[one sendNext:@"one"];
[two sendNext:@"two"];
concat合并
按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号
zip
zip:是把多个信号压缩成一个信号,当每个信号都有返回值时压缩成一个元组(RACTuple)返回,元组内值的顺序只与压缩顺序有关。
merge
/*
此代码可以将merge:后数组中的信号合并为一个信号。只有有任意一个信号完成信息的发送。那么合并后的信号就可以正常的接收到信号。
*/
RACSubject * one = [RACSubject subject];
RACSubject * two = [RACSubject subject];
[[RACSignal merge:@[one,two]] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@"信号发送combineLatest,%@",x);
}];
// [one sendNext:@"one"];
[two sendNext:@"two"];
flattenMap 信号过滤
flattenMap 的底层实现是通过bind实现的。拿到原数据,处理完成之后,包装成信号返回
[[self.textField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
return [RACSignal return:[NSString stringWithFormat:@"输入文本: %@", value]];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"输入文本 : %@", x);
}];
Map 信号过滤
flattenMap 的底层实现是通过bind实现的。拿到原数据,处理完成之后,包装成信号返回
[self.textField.rac_textSignal map:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
return [NSString stringWithFormat:@"输入文本: %@", value]];
}]
在界面中写一波
需求:账号与密码都输入后登录才可以点击,登录按钮变颜色
//登录按钮点击
[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"button点击了");
}];
//登录按钮是否有效
RAC( self.button ,enabled) = [RACSignal combineLatest:@[self.accountTF.rac_textSignal,self.psdTF.rac_textSignal ] reduce:^id (NSString *string, NSString *number) {
NSLog(@"====%@%@",string,number);
return @(string.length && number.length);
}];
//登录按钮颜色改变
RAC(self.button,backgroundColor) = [RACSignal combineLatest:@[self.accountTF.rac_textSignal,self.psdTF.rac_textSignal] reduce:^id _Nonnull(NSString * account,NSString * psd){
UIColor * color = [UIColor grayColor];
if (account.length&& psd.length) {
color = [UIColor orangeColor];
}
return color;
}];
//账号
[[self.accountTF rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"输入账号: %@",x);
}];
//密码
[[self.psdTF rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"输入密码; %@",x);
}];
算一点点运用了,只是登录接口该怎么写还不会。哈哈~
网友评论