做iOS开发已经8个年头了,记得上次使用RAC
应该是2015年那会了,过了6年感觉已经要将RAC忘的差不多了,最近公司项目比较宽松花了点时间重新复习了下RAC
, 然后写下这篇Blog加深下记忆。
RAC 框架的流程围绕着 RACSignal
的 创建、订阅、发送、销毁等;
本篇不进行源码的解读,源码的学习个人建议还是打开 xcode
认真研读来的更有效直观, 以下是 RACSignal
的 创建、订阅、发送 逻辑图;
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、cocompleted
9.获取信号中的信号:switchToLatest
10.信号错误重试:retry
RACSignal
创建、发送、订阅//1、创建
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
// 3:发送信号
[subscriber sendNext:@"Cooci"];
// 4:销毁
return [RACDisposable disposableWithBlock:^{
NSLog(@"我们销毁了");
}];
}];
// 2: 订阅信号
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"0:订阅到了:%@",x);
}];
2、RACSubject
即能 发送信号 也能 订阅信号
// 子类 --- 发送信号还能订阅
RACSubject *subject = [RACSubject subject];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[subject sendNext:@"三文鱼"];
3、让 Signal 的产生只执行一次(RACMulticastConnection
)
// 1:创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"信号产生了");
// 3:信号发送
[subscriber sendNext:@"abc"];
// 4:销毁信号
return [RACDisposable disposableWithBlock:^{
NSLog(@"销毁了");
}];
}];
RACMulticastConnection *connect = [signal publish];
// connect.signal ---> subject add subcriber ---> subject.subcribers
// 2:信号订阅 ---> 信号订阅的产生 ---- signal
// 循环 --- 遍历 sendNext --- 都能来
[connect.signal subscribeNext:^(id _Nullable x) {
NSLog(@"1:订阅到了%@",x);
}];
// 2:信号订阅 ---> 信号订阅的产生 ---- signal
[connect.signal subscribeNext:^(id _Nullable x) {
NSLog(@"2:订阅到了%@",x);
}];
// 2:信号订阅 ---> 信号订阅的产生 ---- signal
[connect.signal subscribeNext:^(id _Nullable x) {
NSLog(@"3:订阅到了%@",x);
}];
// 函数 ---> signal 产生只执行一次
[connect connect];
4、替代KVO
的写法
[RACObserve(self, username) subscribeNext:^(NSString *newName) {
NSLog(@"%@", newName);
}];
5、对象属性 绑定到signal
//示例1
RAC(self.loginVM,account) = self.accountTF.rac_textSignal;
//示例2
RAC(self, passwordEnable) = [RACSignal combineLatest:@[RACObserve(self, password), RACObserve(self, passwordConfirmation)] reduce:^(NSString *password, NSString *passwordConfirm) {
return @([passwordConfirm isEqualToString:password]);
}];
6、Sequence 序列遍历处理(RACSequence)
//常规处理
NSMutableArray *results = [NSMutableArray array];
for (NSString *str in strings) {
if (str.length < 2) {
continue;
}
NSString *newString = [str stringByAppendingString:@"foobar"];
[results addObject:newString];
}
//RACSequence 方式
RACSequence *results = [[strings.rac_sequence
filter:^ BOOL (NSString *str) {
return str.length >= 2;
}]
map:^(NSString *str) {
return [str stringByAppendingString:@"foobar"];
}];
7、RACCommand
方式
@weakify(self);
// 初始command
self.loginCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
@strongify(self);
// 网络信号 --- 成功 -- 失败 -- 状态
NSLog(@"input === %@",input);
//return [RACSignal empty];
return [self loginRequest];
}];
// 成功
[[self.loginCommand.executionSignals switchToLatest] subscribeNext:^(id _Nullable x) {
NSLog(@"switchToLatest == %@",x);
}];
// 失败
[self.loginCommand.errors subscribeNext:^(NSError * _Nullable x) {
NSLog(@"errors == %@",x);
@strongify(self);
}];
// 状态
[[self.loginCommand.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
NSLog(@"executing == %@",x);
@strongify(self);
if ([x boolValue]) {
//command处于执行状态
} else {
//command处于非执行状态
}
}];
//执行command
[self.loginCommand execute:@"登录"];