RACSignal
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber){
[subscriber sendNext: @1]
return nil;
}];
RACSubject
作用:可以代替代理(protocol)
RACMulticastConnection
作用:解决RACSignal的副作用问题
RACSignal副作用:当多次执行 [signal subscribeNext:]
方法的时候,singal中的block就会执行多次
解决方式:
在执行 [signal subscribeNext:]
之前,把RACSignal转化为RACMulticastConnection
RACMulticastConnection *connection = [signal publish];
[connection.signal subscribeNext:^(id x)({
}];
[connection.signal subscribeNext:^(id x)({
}];
//进行连接
[connection connect];
这样之后,尽管subscribeNext方法调用了两次,但是在singal中的block也只会执行一次
原理:创建一个RACSubject
订阅signal
RACCommand
作用:用于处理事件的类
注意点:
1. RACCommand内部必需要返回signal
2. executionSignals 信号中信号,一开始获取不到内部信号
1. switchToLatest:获取最近的内部信号
2. execute:获取内部信号
3. executing:判断是否正在执行
1. 第一次不准确,需要skip跳过
2. 一定要记得sendCompleted,否则永远不会执行完成
4. execute执行,执行command的block
基本使用:
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"执行block");
return [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@2];
[subscriber sendCompleted];
return nil;
}];
}];
// 执行第一种方式
// [[command execute:@1] subscribeNext:^(id _Nullable x) {
// NSLog(@"1111---%@", x);
// }];
//执行第二种方式
// [command.executionSignals subscribeNext:^(id _Nullable x) {
//
// NSLog(@"2222-%@", x);
// [x subscribeNext:^(id _Nullable x) {
// NSLog(@"3333-%@", x);
// }];
// }];
//执行第三种方式
[command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"4444-%@", x);
}];
//监听信号的执行情况, skip跳过第一次,第一次不准确
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
BOOL isExecuting = [x boolValue];
if (isExecuting) {
NSLog(@"正在执行");
} else {
NSLog(@"执行完成");
}
}];
[command execute:@1];
场景:监听按钮点击,网络请求
//第一种创建方式
// self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
// NSLog(@"111--%@", input);
//
// return [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
//
// [subscriber sendNext:input];
// [subscriber sendCompleted];
// return nil;
// }];
// }];
//第二种创建方式
RACSubject *subject = [RACSubject subject];
self.button.rac_command = [[RACCommand alloc] initWithEnabled:subject signalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:input];
[subscriber sendCompleted];
return nil;
}];
}];
[[self.button.rac_command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
//控制按钮是否可以点击
[subject sendNext:@(![x boolValue])];
}];
//监听按钮点击
[self.button.rac_command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"222--%@", x);
}];
rac_signalForSelector 监听一个方法是否被调用
KVO rac_valuesForKeyPath或RACObserve
@property (nonatomic) int age;
//第一种方式
[[self rac_valuesForKeyPath:@keypath(self, age) observer:self] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
//第二种方式,宏
[RACObserve(self, age) subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.age++;
}
rac_signalForControlEvents 监听按钮事件
[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@", x);
}];
rac_addObserverForName 通知
//监听通知
//不需要管理观察者,RAC内部已经管理
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"Noti" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@", x);
}];
//发出通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"Noti" object:nil];
rac_textSignal textfiled文字改变
@weakify(self);
[self.field.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@", x);
@strongify(self);
self.button.enabled = x.length;
}];
RAC绑定
RAC(self.label, text) = self.field.rac_textSignal;
rac_liftSelector 序列,可以代替GCD
RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@"第一个数据"];
return nil;
}];
RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@"第二个数据"];
return nil;
}];
//Selector:当数组中所有信息都发送next的时候调用
//rac_liftSelector必要条件:有几个信号,方法就必须有几个参数,参数就是信号发出的值
[self rac_liftSelector:@selector(reloadDataFirst:second:) withSignals:signal1, signal2, nil];
- (void)reloadDataFirst:(NSString *)first second:(NSString *)second {
NSLog(@"%@, %@", first, second);
}
bind 绑定,可以拦截数据进行处理之后再返回
[[self.field.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
return ^ RACSignal * (id value, BOOL *stop) {
NSString *result = [NSString stringWithFormat:@"%@%@", value, @"xb"];
return [RACReturnSignal return:result];
};
}] subscribeNext:^(id _Nullable x) {
NSLog(@"获取处理完的数据 %@", x);
}];
flattenMap 返回的是一个信号
[[self.field.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
NSString *result = [NSString stringWithFormat:@"%@%@", value, @"xb"];
return [RACReturnSignal return:result];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"获取处理完的数据 %@", x);
}];
map 返回的是一个值
[[self.field.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
NSString *result = [NSString stringWithFormat:@"%@%@", value, @"xb"];
return result;
}] subscribeNext:^(id _Nullable x) {
NSLog(@"获取处理完的数据 %@", x);
}];
concat 拼接
//RACSubject 按顺序发送
//RACReplaySubject 可以不按顺序发送
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACReplaySubject subject];
NSMutableArray *array = [NSMutableArray array];
//按顺序拼接,必须第一个信号发送完成,第二个信号才能获取值
[[signalA concat:signalB] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
[array addObject:x];
}];
[signalB sendNext:@"B"];
[signalA sendNext:@"A"];
[signalA sendCompleted];
NSLog(@"%@", array);
/*
A
B
(A,B)
*/
then:拼接, 忽略掉上一个信号的值
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
NSLog(@"执行信号A");
[subscriber sendNext:@1];
[subscriber sendCompleted];
return nil;
}];
//then:拼接, 忽略掉上一个信号的值
//可以解决block嵌套的问题
[[signalA then:^RACSignal * _Nonnull{
return [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
NSLog(@"执行信号B");
[subscriber sendNext:@2];
[subscriber sendCompleted];
return nil;
}];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
/*
执行信号A
执行信号B
2
*/
merge 合并
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
//merge, 合并,只要任何一个信号发送,就能订阅,无序的整合信号数据
[[signalA merge:signalB] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
[signalB sendNext:@"B"];
[signalA sendNext:@"A"];
/*
B
A
*/
zipWith 压缩信号成元组
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
//zipWith, 压缩,同时发送数据,压缩信号数据变成元组
[[signalA zipWith:signalB] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
RACTupleUnpack(NSString *a, NSString *b) = x;
NSLog(@"%@ %@", a, b);
}];
[signalA sendNext:@"A"];
[signalB sendNext:@"B"];
combineLatestWith 合并, 任何一个信号,只要改变就能订阅到
//最多合并两个
[[self.field.rac_textSignal combineLatestWith:self.pwdField.rac_textSignal] subscribeNext:^(RACTwoTuple * _Nullable x) {
RACTupleUnpack(NSString *name, NSString *password) = x;
self.button.enabled = (name.length > 0 && password.length);
NSLog(@"%@", x);
}];
combineLatest 合并多个, reduce 聚合
//reduce 聚合,把多个信号的值,聚合为一个值
//reduce参数:几个信号就几个参数,每个参数就是信号发出的值
[[RACSignal combineLatest:@[self.field.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id _Nullable (NSString *name, NSString *password){
NSLog(@"%@ %@", name, password);
return @(name.length > 0 && password.length > 0);
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
self.button.enabled = [x boolValue];
}];
//RAC的写法, 响应式编程(绑定)
RAC(self.button, enabled) = [RACSignal combineLatest:@[self.field.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id _Nullable (NSString *name, NSString *password){
NSLog(@"%@ %@", name, password);
return @(name.length > 0 && password.length > 0);
}];
filter 过滤
[[self.field.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
return value.length >= 6;
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@", x);
}];
interval定时器
//RACScheduler:多线程,管理线程
[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
NSLog(@"%@", x);
}];
delay 延迟发送数据
[[[RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@"a"];
[subscriber sendCompleted];
return nil;
}] delay:2] subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];