RACDisposable disposable 销毁
RACScheduler scheduler 调度
RACCommand command 命令
RACSignal signal 信号
RACSubject subject
RACReplaySubject
RACStream
RACSequence sequence 序列
RACTuple tuple 元组,重数
RACSubscriber subscribe 订阅
RACCompoundDisposable compound 复合的;混合的
1、信号映射:map、flattenMap
2、信号过滤:filter、ignore、distinctUntilChanged
3、信号合并:combineLatest、reduce、merge、zipWith
4、信号连接:concat、then
5、信号操作时间:timeout、interval、dely
6、信号取值:take、takeLast、takeUntil
7、信号跳过:skip
8、信号发送顺序:donext、completed
9、获取信号中的信号:switchToLatest
10、信号错误重试:retry
创建信号、订阅信号、发送信号、销毁信号
https://github.com/ReactiveCocoa/ReactiveObjC
pod 'ReactiveObjC'
导入头文件 #import <ReactiveObjC.h>
基本使用一
//1.创建信号 创建信号对象 然后创建一个可变数组!
RACSubject * subject = [RACSubject subject];
//2.订阅信号 创建一个订阅者 将Block保存到订阅者中 , 将订阅者保存到上面的数组中
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
//3.发送信号 遍历信号对象中的数组,取出订阅对象! 调用订阅对象中的Block 执行!!
[subject sendNext:@"dyz"];
基本使用二
//1:创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//3:发送信号
[subscriber sendNext:@"dyz"];
[subscriber sendCompleted];//RAC中不加这一句也可以 销毁,但是在RxSwift中必须加上这句,否则 无法销毁
//4:销毁信号
return [RACDisposable disposableWithBlock:^{
NSLog(@"销毁了");
}];
}];
//2:订阅信号。只有订阅了信号,才会激活信号
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
//3:发送信号
//4:销毁信号
监听方法
[[self.dYZView rac_signalForSelector:@selector(send:)] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@"监听到了!!%@",x);
RACTuple *tuple = x;
NSLog(@"%@",tuple.first);//haha!!
}];
#import "DYZView.h"
@implementation DYZView
-(IBAction)btnClick:(id)sender{
[self send:@"haha!!"];
}
-(void)send:(id)objc{
}
@end
[[self rac_signalForSelector:@selector(viewWillAppear:)] subscribeNext:^(RACTuple * _Nullable x) {
}];
监听代理
[[self rac_signalForSelector:@selector(textFieldDidBeginEditing:) fromProtocol:@protocol(UITextFieldDelegate)] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@"%@",x);
}];
self.textField.delegate = self;
KVO
//KVO
// [self.hkView rac_observeKeyPath:@"frame" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
// NSLog(@"%@",value);
// }];
[[self.hkView rac_valuesForKeyPath:@"frame" observer:nil] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
self.person = [[Person alloc] init];
self.person.car = @"car";
// 这里已经有回调了所以 observer可以置为nil,随便写一个也可以,就写self吧
[[self.person rac_valuesForKeyPath:@"car" observer:nil] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
//宏实现
//1、
[RACObserve(self.view, frame) subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
//2、
[RACObserve(self, name) subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
self.name = @"dyz";
监听事件
//可以选择button Event类型
[[self.btn rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@",x);
}];
//默认是UIControlEventTouchUpInside类型
self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"%@",input);
return [RACSignal empty];
}];
通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@",x);
}];//object 传字符串 不行ser
textFiled
[_textFiled.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x);
}];
// 加skip 解决最开始开一次
[[self.textField.rac_textSignal skip:1] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x);
}];
//宏实现
//用来给某个对象的某个属性绑定信号,只要产生信号内容,就会将内容赋值给属性!!
RAC(_label,text)=_textField.rac_textSignal;
定时器
//1、
[[RACSignal interval:1.0 onScheduler:[RACScheduler scheduler]] subscribeNext:^(NSDate * _Nullable x) {
NSLog(@"%@",[NSThread currentThread]);//子线程 滑动UI不会卡顿
}];
//2、
[[RACSignal interval:1 onScheduler:[RACScheduler schedulerWithPriority:(RACSchedulerPriorityHigh) name:@"com.ReactiveCocoa.RACScheduler.mainThreadScheduler"]] subscribeNext:^(NSDate * _Nullable x) {
NSLog(@"%@",[NSThread currentThread]);
}];
手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
self.label.userInteractionEnabled = YES;
[self.label addGestureRecognizer:tap];
[tap.rac_gestureSignal subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
NSLog(@"%@",x);
}];
数组 字典遍历
NSArray *array = @[@"dyz",@"123",@"18"];
[array.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
NSDictionary *dict = @{@"key":@"dyz",@"age":@"18",@"gender":@"1"};
[dict.rac_sequence.signal subscribeNext:^(id _Nullable x) {
//元祖
NSLog(@"%@",x);
RACTwoTuple *tuple = (RACTwoTuple *)x;
NSLog(@"key == %@ , value = %@",tuple[0],tuple[1]);
}];
循环引用
#import "ViewController.h"
#import <ReactiveObjC.h>
@interface ViewController ()
@property(nonatomic,strong)RACSignal * signal;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
@weakify(self);
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
@strongify(self);
NSLog(@"%@",self);
return nil;
}];
_signal = signal;
}
- (IBAction)dismiss:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)dealloc
{
NSLog(@"成功的走了!!");
}
映射 flattenMap
// flattenMap作用:把源信号的内容映射成一个新的信号,信号可以是任意类型。
// flattenMap使用步骤:
// 1.传入一个block,block类型是返回值RACStream,参数value
// 2.参数value就是源信号的内容,拿到源信号的内容做处理
// 3.包装成RACReturnSignal信号,返回出去。
// flattenMap底层实现:
// 0.flattenMap内部调用bind方法实现的,flattenMap中block的返回值,会作为bind中bindBlock的返回值。
// 1.当订阅绑定信号,就会生成bindBlock。
// 2.当源信号发送内容,就会调用bindBlock(value, *stop)
// 3.调用bindBlock,内部就会调用flattenMap的block,flattenMap的block作用:就是把处理好的数据包装成信号。
// 4.返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号。
// 5.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。
[[self.textField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
NSLog(@"处理:%@",value);
return [RACReturnSignal return:[NSString stringWithFormat:@"dyz:%@",value]];//#import <RACReturnSignal.h>
}] subscribeNext:^(id _Nullable x) {
NSLog(@"逻辑处理:%@",x);
}];
map
- map 和 flattenMap的效果相似
[[self.textField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
NSLog(@"处理:%@",value);
return [NSString stringWithFormat:@"dyz:%@",value];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"逻辑处理:%@",x);
}];
过滤 filter
[[self.textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
if (self.textField.text.length > 6) {
self.textField.text = [self.textField.text substringToIndex:6];
return NO;
} else {
return YES;//返回为YES时,才会走到下面
}
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"--%@++",x);
}];
bind
// 方式二:在返回结果前,拼接,使用RAC中bind方法做处理。
// bind方法参数:需要传入一个返回值是RACStreamBindBlock的block参数
// RACStreamBindBlock是一个block的类型,返回值是信号,参数(value,stop),因此参数的block返回值也是一个block。
// RACStreamBindBlock:
// 参数一(value):表示接收到信号的原始值,还没做处理
// 参数二(*stop):用来控制绑定Block,如果*stop = yes,那么就会结束绑定。
// 返回值:信号,做好处理,在通过这个信号返回出去,一般使用RACReturnSignal,需要手动导入头文件RACReturnSignal.h。
// bind方法使用步骤:
// 1.传入一个返回值RACStreamBindBlock的block。
// 2.描述一个RACStreamBindBlock类型的bindBlock作为block的返回值。
// 3.描述一个返回结果的信号,作为bindBlock的返回值。
// 注意:在bindBlock中做信号结果的处理。
// 底层实现:
// 1.源信号调用bind,会重新创建一个绑定信号。
// 2.当绑定信号被订阅,就会调用绑定信号中的didSubscribe,生成一个bindingBlock。
// 3.当源信号有内容发出,就会把内容传递到bindingBlock处理,调用bindingBlock(value,stop)
// 4.调用bindingBlock(value,stop),会返回一个内容处理完成的信号(RACReturnSignal)。
// 5.订阅RACReturnSignal,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。
// 注意:不同订阅者,保存不同的nextBlock,看源码的时候,一定要看清楚订阅者是哪个。
// 这里需要手动导入#import <ReactiveCocoa/RACReturnSignal.h>,才能使用RACReturnSignal。
[[self.textField.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
return ^RACSignal * (id _Nullable value, BOOL *stop) {
return [RACReturnSignal return:[NSString stringWithFormat:@"输出:%@",value]];
};
}] subscribeNext:^(id _Nullable x) {
NSLog(@"subscribeNext == %@",x);
}];
组合 combineLatest
两个信号都执行过之后,才会触发,不存在什么记忆
RACSignal *signalA = self.textField.rac_textSignal;
RACSignal *signalB = [self.button rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *comSig = [signalA combineLatestWith:signalB];
[comSig subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
RACSignal *signalA = self.textField.rac_textSignal;
RACSignal *signalB = [self.button rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id _Nonnull(id value1,id value2){//value1和value2 的类型 必须是 OC类型
return [NSString stringWithFormat:@"reduce == %@ ++ %@",value1,value2];//返回的类型也必须是OC类型
}];
[reduceSignal subscribeNext:^(id _Nullable x) {
NSLog(@"subscribeNext == %@",x);
}];
}
contact
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"dyz"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"iOS"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *contactSignal = [signalA concat:signalB];
[contactSignal subscribeNext:^(id _Nullable x) {
NSLog(@"==%@++",x);
}];
2020-08-06 17:16:35.429844+0800 DemoOC[13105:3549275] ==dyz++
2020-08-06 17:16:35.430114+0800 DemoOC[13105:3549275] ==iOS++
then
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"dyz"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"iOS"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *sigThen = [signalA then:^RACSignal * _Nonnull{
return signalB;
}];
[sigThen subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
2020-08-06 17:27:59.940039+0800 DemoOC[13324:3560206] iOS
merge
// merge:把多个信号合并成一个信号
//创建多个信号
RACSignal *signalA = [self.textField.rac_textSignal skip:1];
RACSignal *signalB = [self.button rac_signalForControlEvents:UIControlEventTouchUpInside];
// 合并信号,任何一个信号发送数据,都能监听到.
RACSignal *mergeSignal = [signalA merge:signalB];
[mergeSignal subscribeNext:^(id _Nullable x) {
NSLog(@"++%@=",x);
}];
zip
//signalA 和 signalB 都触发了,才能监听到。并且会一一对应,就是signalA的第二次触发会对应signalB的第二次触发,signalA的第三次触发会对应signalB的第三次触发。相当于有个记忆的能力。
RACSignal *signalA = [self.textField.rac_textSignal skip:1];
RACSignal *signalB = [self.button rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *signalZip = [signalA zipWith:signalB];
[signalZip subscribeNext:^(id _Nullable x) {
NSLog(@"++%@=",x);
}];
Ignore
distinctUntilChanged
// 当上一次的值和当前的值有明显的变化就会发出信号,否则会被忽略掉。
//在开发中,刷新UI经常使用,只有两次数据不一样才需要刷新
RACSubject *subject = [RACSubject subject];
[[subject distinctUntilChanged] subscribeNext:^(id _Nullable x) {
NSLog(@"++%@=",x);
}];
// 发送信号
[subject sendNext:@"1"];
[subject sendNext:@"2"];
[subject sendNext:@"2"];
skip
//表示输入第一次,不会被监听到,跳过第一次发出的信号
[[self.textField.rac_textSignal skip:1] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"++%@=",x);
}];
[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] skip:1] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"++%@=",x);
}];
take
// take:可以屏蔽一些值,取前面几个值---这里take为2 则只拿到前两个值
RACSubject *subject = [RACSubject subject];
[[subject take:2] subscribeNext:^(id _Nullable x) {
NSLog(@"==%@+",x);
}];
// 发送信号
[subject sendNext:@"111"];
[subject sendNext:@"112"];
[subject sendNext:@"113"];
takeLast
//takeLast:和take的用法一样,不过他取的是最后的几个值,如下,则取的是最后两个值
//注意点:takeLast 一定要调用sendCompleted,告诉他发送完成了,这样才能取到最后的几个值
RACSubject *subject = [RACSubject subject];
[[subject takeLast:2] subscribeNext:^(id _Nullable x) {
NSLog(@"++%@=",x);
}];
[subject sendNext:@"111"];
[subject sendNext:@"112"];
[subject sendNext:@"113"];
[subject sendCompleted];
takeUntil
// takeUntil:---给takeUntil传的是哪个信号,那么当这个信号发送信号或sendCompleted,就不能再接受源信号的内容了。
RACSubject *subjectA = [RACSubject subject];
RACSubject *subjectB = [RACSubject subject];
[[subjectA takeUntil:subjectB] subscribeNext:^(id _Nullable x) {
NSLog(@"==%@+",x);
}];
[subjectA sendNext:@"1"];
[subjectA sendNext:@"2"];
// [subjectB sendNext:@"3"];
[subjectB sendCompleted];
[subjectA sendNext:@"4"];
switchToLatest
RACSubject *signalOfSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
// 获取信号中信号最近发出信号,订阅最近发出的信号。
// 注意switchToLatest:只能用于信号中的信号
[signalOfSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[signalOfSignals sendNext:signal];
[signal sendNext:@1];
[signal sendNext:@"123"];
timeout
RACSignal *signal = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
return nil;
}] timeout:1 onScheduler:[RACScheduler scheduler]];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
} error:^(NSError * _Nullable error) {
NSLog(@"%@",error);
}];
网友评论