文章内容:
代理
简单使用
基于UIKitFoundation (Foundation对象)
RACSubject冷信号和热信号
KVO事件信号
网络请求
RACCommand
RACMulticastConnection
信号的调度器RACScheduler(线程)
RACChannelTo
代理
- (RACSignal<RACTuple *> *)rac_signalForSelector:(SEL)selector;
- (RACSignal<RACTuple *> *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol;
简单使用
//信号创建
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//任何时候,都可以发送信号,可以异步
[subscriber sendNext:@"发送信号"];
//数据传递结束,最好调用sendCompleted,代表命令执行结束
[subscriber sendCompleted];
return nil;
}];
//信号订阅
RACDisposable *disposable = [signal subscribeNext:^(id _Nullable x) {
//收到信号;
NSLog(@"收到的信号内容");
}];
self.keyboardDisposable = disposable;
//取消订阅
[disposable dispose];
基于UIKit
//1. rac_textSignal 文本监听信号,可以减少对代理方法的依赖
//UITextField创建了一个 `textSignal`的信号,并订阅了该信号
// 当UITextField的内容发生改变时,就会回调subscribeNext
//当UITextField内输入的内容长度大于5时,才会回调subscribeNext
//2. filter 订阅的信号进行筛选
[[[textFid rac_textSignal] filter:^BOOL(NSString * _Nullable value) {
return value.length > 5;
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"filter result = %@", x);
}];
//3. ignore 对订阅的信号进行过滤
[[[textFid rac_textSignal] ignore:@"666"] subscribeNext:^(NSString * _Nullable x) {
//当输入的内容 equalTo @"666" 时,这里不执行
//其他内容,均会执行subscribeNext
NSLog(@"ignore = %@", x);
}];
//UIButton rac_signalForControlEvents 创建事件监听信号
//当UIButton点击时,会调用subscribeNext
[[button rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"666");
UIViewController *secVC = [[CTMediator sharedInstance] YQ_createSearchCoursesViewControllerWithForwardSource:@""];
// UIViewController *secVC = [[CTMediator sharedInstance] performTarget:@"SecondVCRouter" action:@"createSearchCoursesViewController" params:nil shouldCacheTarget:NO];
[self presentViewController:secVC animated:YES completion:nil];
}];
// 手势 信号
[[tapGesture rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
NSLog(@"tapGesture");
@strongify(self);
[self.viewModel.clickAdCommand execute:nil];//RACCommand 执行
}];
Foundation (Foundation对象)
//1.NSNotificationCenter 通知
//NSNotificationCenter 监听了APP退到后台的事件。最重要的一点就是不需要移除通知,比通知用起来更爽,无后顾之忧!!!
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"NSNotificationCenter UIApplicationDidEnterBackgroundNotification");
}];
@property (nonatomic, strong) RACDisposable *keyboardDisposable;
self.keyboardDisposable = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@ 键盘弹起", x); // x 是通知对象
}];
//注意:rac_addObserverForName同样需要移除监听。RAC通知监听会返回一个RACDisposable清洁工的对象,在dealloc中销毁信号,信号销毁时,RAC在销毁的block中移除了监听
// 2、 interval定时器 (程序进入后台,再重新进入前台时,仍然有效,内部是用GCD实现的)
//创建一个定时器,间隔1s,在主线程中运行
RACSignal *timerSignal = [RACSignal interval:1.0f onScheduler:[RACScheduler mainThreadScheduler]];
//定时器总时间3秒
timerSignal = [timerSignal take:6];
//定义一个倒计时的NSInteger变量
self.counter = 6;
@weakify(self)
[timerSignal subscribeNext:^(id _Nullable x) {
@strongify(self)
self.counter--;
NSLog(@"count = %ld", (long)self.counter);
} completed:^{
//计时完成
NSLog(@"Timer completed");
}];
// 3、delay延迟
//创建一个信号,2秒后订阅者收到消息
[[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
return nil;
}] delay:2] subscribeNext:^(id _Nullable x) {
NSLog(@"delay : %@", x);
}];
// 3.数组遍历。rac_sequence
NSArray *array = @[@"8", @"2", @"6", @"4", @"3"];
[array.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"数组内容:%@", x);
}];
// 5、NSDictionary字典遍历 Tuple 元组
NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3",@"key4":@"value4", @"key5":@"value5", @"key3":@"value3",@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
[dictionary.rac_sequence.signal subscribeNext:^(id _Nullable x) {
// x 是一个元祖,这个宏能够将 key 和 value 拆开 乱序
RACTupleUnpack(NSString *key, NSString *value) = x;
NSLog(@"Tuple字典内容:%@ : %@", key, value);
}];
RACSubject
RACSubject
在 RACSignal
对象之上进行了简单的修改,将原有的冷信号改造成了热信号,将不可变变成了可变。
-
这个类即可以创建信号, 也可以发送信号
-
RACSubject
是时间相关的,订阅者接收到多少值取决于它订阅的时间。 -
RACSubject
是RACSignal
和RACSubcriber
的结合体。(实现了RACSubscriber
协议)
冷信号和热信号
冷信号是被动的,只会在被订阅时向订阅者发送通知;热信号是主动的,它会在任意时间发出通知,与订阅者的订阅时间无关。
也就是说冷信号所有的订阅者会在订阅时收到完全相同的序列;而订阅热信号之后,只会收到在订阅之后发出的序列。
热信号的订阅者能否收到消息取决于订阅的时间。
//6、RACSubject代理
DelegateView.h
@interface DelegateView : UIView
@property (nonatomic, strong) RACSubject *delegateSignal;
@end
DelegateView.m
//触发 发送消息
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 判断代理信号是否有值
if (self.delegateSignal) {
// 有值,给信号发送消息
[self.delegateSignal sendNext:@666];
}
}
Controller
//使用前,记得初始化。
//注意 必须先订阅,再发送消息才可以接收到消息。
self.delegageView.delegateSignal = [RACSubject subject];
[self.delegageView.delegateSignal subscribeNext:^(id _Nullable x) {
//订阅到 666 的消息
NSLog(@"RACSubject result = %@", x);
}];
7. //RACReplaySubject
/**
只要发送信号 都可以在订阅的block中收到信号。
*/
// 创建信号
RACReplaySubject *replaySubject = [RACReplaySubject subject];
// 订阅信号
[replaySubject subscribeNext:^(id x) {
NSLog(@"订阅者一接收到信号: %@", x);
}];
// 发送数据
[replaySubject sendNext:@"hello, RAC."];
// 订阅信号
[replaySubject subscribeNext:^(id x) {
NSLog(@"订阅者二接收到信号: %@",x);
}];
******打印****** RACObjC[9640:87566] 订阅者一接收到信号: hello, RAC.
******打印****** RACObjC[9640:87566] 订阅者二接收到信号: hello, RAC.
#pragma mark 对比RACSubject
/**
必须先订阅,再发送消息才可以接收到信号。
*/
// 创建信号
RACSubject *subject = [RACSubject subject];
// 订阅信号
[subject subscribeNext:^(id x) {
NSLog(@"订阅者二接收到信号: %@",x);
}];
// 发送数据
[subject sendNext:@"hello, RAC."];
// 订阅信号
[subject subscribeNext:^(id x) {
NSLog(@"订阅者一接收到信号: %@", x);
}];
****打印***** RACObjC[9585:85299] 订阅者二接收到信号: hello, RAC.
KVO
//1、rac_valuesForKeyPath 通过keyPath监听
[[self.delegageView rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id _Nullable x) {
NSLog(@"kvo = %@", x);
}];
self.delegageView.frame = CGRectMake(10, 210, 200, 200);//当DeletateView的Frame发生变化的时候收到消息。
// 2、RACObserve 属性监听
// 在进行监听时,同样可以使用filter信号,对值进行筛选
// @property (nonatomic, assign) NSInteger KVOObject;
[[RACObserve(self, self.KVOObject) filter:^BOOL(id _Nullable value) {
return [value intValue] >= 2;
}] subscribeNext:^(id _Nullable x) {
NSLog(@"RACObserve : value = %@", x);
}];
self.KVOObject = 1;//当KVOObject属性的值大于等于2的时候,收到信号。
//3. RAC 事件绑定
//当UITextField输入的内容为@"666"时,bView视图的背景颜色变为grayColor
RAC(self.delegageView, backgroundColor) = [self.textFid.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
return [value isEqualToString:@"666"] ? [UIColor grayColor] : [UIColor greenColor];
}];
//登录框 用户名和密码输入正确时,登录按钮才可以点击
事件信号
//1、RACTuple 元祖
//只能存储OC对象 可以用于解包或者存储对象
//解包数据 如:三.5 字典遍历
// RACTupleUnpack(NSNumber *a, NSNumber *b) = x;
// 2、bind 包装
//获取到信号返回的值,包装成新值, 再次通过信号返回给订阅者
[[self.textFid.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
return ^RACSignal *(id value, BOOL *stop){
return [RACSignal return:[NSString stringWithFormat:@"hello %@", value]];
};
}] subscribeNext:^(id _Nullable x) {
NSLog(@"bind %@", x);
}];
// 3、concat 合并
//按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"A"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"B"];
[subscriber sendCompleted];
return nil;
}];
// 把signalA拼接到signalB后,signalA发送完成,signalB才会被激活 顺序执行
[[signalA concat: signalB] subscribeNext:^(id _Nullable x) {
//先拿到 signalA 的结果 , 再拿到 signalB 的结果 , 执行两次
NSLog(@"concat %@", x);
}];
//4、then 下一个
//用于连接两个信号,当第一个信号完成,才会连接then返回的信号
// 底层实现 1.使用concat连接then返回的信号 2.先过滤掉之前的信号发出的值
[[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendCompleted];
return nil;
}] then:^RACSignal *{
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//可以对第一个信号的数据进行过滤处理 , 不能直接获得第一个信号的数据返回值
[subscriber sendNext:@2];
return nil;
}];
}] subscribeNext:^(id x) {
// 只能接收到第二个信号的值,也就是then返回信号的值
NSLog(@"then : %@",x); // 2
}];
//5.merge 合并
// 把多个信号合并为一个信号,任何一个信号有新值的时候就会调用
// 创建多个信号
RACSignal *mergeSignalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *mergeSignalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 合并信号,只要有信号发送数据,都能监听到.
RACSignal *mergeSignal = [mergeSignalA merge:mergeSignalB];
[mergeSignal subscribeNext:^(id x) {
//每次获取单个信号的值
NSLog(@"merge : %@",x);
}];
//6、zipWith 压缩
/**
把两个信号压缩成一个信号,只有当两个信号都发出一次信号内容后,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件(组合的数据都是一一对应的)
*/
RACSignal *zipSignalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
return nil;
}];
RACSignal *zipSignalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//1秒后执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@10];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@20];
});
return nil;
}];
RACSignal *zipSignal = [zipSignalA zipWith:zipSignalB];
[zipSignal subscribeNext:^(id _Nullable x) {
// x 是一个元祖
RACTupleUnpack(NSNumber *a, NSNumber *b) = x;
NSLog(@"zip with : %@ %@", a, b);
//第一次输出 1 10
//第二次输出 2 20
}];
// 7.combineLatest 结合
/**
将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号 (combineLatest 与 zipWith不同的是,每次只拿各个信号最新的值)
*/
RACSignal *combineSignalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
return nil;
}];
RACSignal *combineSignalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@3];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@5];
});
return nil;
}];
RACSignal *combineSignal = [combineSignalA combineLatestWith:combineSignalB];
[combineSignal subscribeNext:^(id _Nullable x) {
// x 是一个元祖
RACTupleUnpack(NSNumber *a, NSNumber *b) = x;
NSLog(@"combineLatest : %@ %@", a, b);
//第一次输出 2 3
//第二次输出 2 5
// 因为combineSignalA中的2是最新数据,所以,combineSignalA每次获取到的都是2
}];
// 8、reduce 聚合
//用于信号发出的内容是元组,把信号发出元组的值聚合成一个值,一般都是先组合在聚合
RACSignal *reduceSignalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *reduceSignalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@3];
return nil;
}];
RACSignal *reduceSign = [RACSignal combineLatest:@[reduceSignalA, reduceSignalB] reduce:^id _Nonnull(NSNumber *a, NSNumber *b){
//reduce中主要是对返回数据的处理
return [NSString stringWithFormat:@"%@ - %@", a, b];
}];
[reduceSign subscribeNext:^(id _Nullable x) {
NSLog(@"reduce %@", x);// a - b
}];
//9、map 数据过滤
/**
map 的底层实现是通过flattenMap 实现的。map 直接对数据进行处理,并且返回处理后的数据
*/
[[self.textFid.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
// 当源信号发出,就会调用这个block,修改源信号的内容
// 返回值:就是处理完源信号的内容。
return [NSString stringWithFormat:@"hello : %@",value];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"Map : %@",x); // hello: "x"
}];
//10、flattenMap 信号过滤
/**
flattenMap 的底层实现是通过bind实现的。拿到原数据,处理完成之后,包装成信号返回
*/
[[self.textFid.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
return [RACSignal return:[NSString stringWithFormat:@"hello : %@", value]];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"flattenMap %@", x);
}];
// 11、filter 过滤
//过滤信号,获取满足条件的信号 参考TextFid RAC
[[self.textFid.rac_textSignal filter:^BOOL(NSString *value) {
return value.length > 6;
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"filter : %@", x); // x 值位数大于6
}];
/**
flatternMap和Map的区别:
FlatternMap中的Block返回信号
Map中的Block返回对象
开发中,如果信号发出的值不是信号,映射一般使用Map
开发中,如果信号发出的值是信号,映射一般使用FlatternMap
*/
网络请求
//使用 @weakify(self) 和 @strongify(self) 避免循环引用
@weakify(self)
[[ViewModel getCourseInfoByTime:0 isExperience:isExperience] subscribeNext:^(id _Nullable x) {
@strongify(self)
//接口请求成功,订阅者可以在这里获取到接口返回的内容 x
} error:^(NSError * _Nullable error) {
@strongify(self)
//当接口出错时,这里可以处理错误信息
}];
/**
解读:(RAC的执行流程)
1、在ViewModel类中,创建了一个信号,这个信号请求了一个获取课程的接口。信号创建之后,并不会立即执行,要等订阅者,订阅并调用subscribeNext时,才会执行。
2、在ViewController中,经过用户操作,开始调用getCourseByIsExperience方法。此时,订阅者开始订阅信号,信号中的createSignal开始执行接口请求方法。
3、当接口请求成功后,根据状态,将对应的object或者error通过sendNext: 和sendError:传递给订阅者
4、订阅者开始执行subscribeNext 或者 error block中的代码
(ps:如果接口请求之后,不需要获取返回值,则可以在信号中这样返回 [subscriber sendNext:nil])
优点:这个接口请求过程,ViewController只需要将接口所需参数传入,即可得到接口的结果,大大简化了控制器层面的内容,使得控制器更加专注于页面之间的业务处理,数据传递等功能。
*/
RACCommand
两种创建方式:
/*
第一种就是直接通过传进一个用于构建RACSignal的block参数来初始化RACCommand,
而block中的参数input为执行command时传入的数据,
另外,创建出的signal可在里面完成一些数据操作,如网络请求,本地数据库读写等等,
而第二种则另外还需要传进一个能传递BOOL事件的RACSignal,
这个signal的作用相当于过滤,当传递的布尔事件为真值时,command能够执行,反之则不行。
*/
- (id)initWithSignalBlock:(RACSignal * (^)(id input))signalBlock; ①
- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock; ②
注意: 伴随着command一
起构建的signal,记得要在操作完成后发送完成消息以表示其执行完了:否则不能再执行此command。
[subscriber sendCompleted];
RACCommand的执行使用下面的这个函数:第一种方式创建的时候作为input参数接收。
- (RACSignal *)execute:(id)input;
订阅RACCommand我们可以使用其内部的属性executionSignals返回一个信号,然后对这个信号进行订阅。
//x是一个RACSignal类型的信号
[[aCommand executionSignals]
subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
在订阅的block中,我们打印了传递事件x的描述,最后会发现x原来是一个RACSignal,原因是RACCommand中的executionSignals属性是一个包裹着信号的信号,其包裹着的信号就是我们当初在创建RACCommand时进行构建的信号,所以当我们开始执行RACCommand时,executionSignals信号就会立即发送事件,传递出其包裹的信号,我们可以对这个信号进行订阅:
//如果你想在RACCommand执行时做某些提示操作(弹出等待框,出现转来转去的菊花),并在执行后取消提示,你可以这样写:
[[aCommand executionSignals]
subscribeNext:^(RACSignal *x) {//对X进行订阅
// 开始提示
[x subscribeNext:^(id x) {
// 关闭提示
// Do something...
}];
}];
switchToLatest 转换写法
[[[aCommand executionSignals]switchToLatest]
subscribeNext:^(id x) {
// Do something...
}];
错误处理
[aCommand.errors
subscribeNext:^(NSError *x) {
NSLog(@"ERROR! --> %@",x);
}];
RACCommand 一般先订阅再执行。 execute 使用的是 RACReplaySubject, 所以可以先执行命令, 再订阅信号
// RACCommand
// 使用场景: 1.监听按钮点击事件; 2.发送网络请求等;
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"%@", input);
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"执行命令产生的数据"];
return nil;
}];
}];
RACSignal *signal = [command execute:@"执行命令"];
// execute 使用的是 RACReplaySubject, 所以可以先执行命令, 再订阅信号
[signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
理解:**
使用场景: 1.监听按钮点击事件; 2.发送网络请求等;
-
View
中发生(或者Controller)中 触发(点击/手势)。- (RACSignal *)execute:(id)input;
-
viewModel中
创建
RACCommand
,走一些逻辑代码 [返回RACSignal (发送消息)] 和 错误返回。 -
控制器中
订阅block块中 得到消息(值)。
RACMulticastConnection
// 需求: 每次订阅信号时不要都发送网络请求, 只发送一次网络请求, 但是每次订阅信号时都要能得到数据
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// connection connect 时执行此 block.
NSLog(@"网络请求");
[subscriber sendNext:@"JSON数据"];
return nil;
}];
// 2.信号转换成连接类
//RACMulticastConnection *connection = [signal publish];
RACMulticastConnection *connection = [signal multicast:[RACReplaySubject subject]];
// 3.订阅连接类的信号
[connection.signal subscribeNext:^(id x) {
// subscriber sendNext 时执行此 block
NSLog(@"订阅者一: %@",x);
}];
[connection.signal subscribeNext:^(id x) {
// subscriber sendNext 时执行此 block
NSLog(@"订阅者二: %@",x);
}];
// 4.连接
[connection connect];
******输出*******
2020-05-11 15:05:25.350601+0800 RACObjC[12517:200796] 网络请求
2020-05-11 15:05:25.350705+0800 RACObjC[12517:200796] 订阅者一: JSON数据
2020-05-11 15:05:25.351078+0800 RACObjC[12517:200796] 订阅者二: JSON数据
多次请求网络版本
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"网络请求");
[subscriber sendNext:@"JSON数据"];
return nil;
}];
[signal subscribeNext:^(id x) {
NSLog(@"订阅者一: %@", x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"订阅者二: %@", x);
}];
******输出*******
2020-05-11 15:05:25.349379+0800 RACObjC[12517:200796] 网络请求
2020-05-11 15:05:25.349932+0800 RACObjC[12517:200796] 订阅者一: JSON数据
2020-05-11 15:05:25.350118+0800 RACObjC[12517:200796] 网络请求
2020-05-11 15:05:25.350219+0800 RACObjC[12517:200796] 订阅者二: JSON数据
信号的调度器RACScheduler
deliverOn
//创建信号
-(void)createUpSignals{
RACSignal * signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"sendTestSignal%@",[NSThread currentThread]);
[subscriber sendNext:@1];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
}];
}];
self.testSignal = signal;
}
//订阅信号
//要想放在主线程执行只要将[RACScheduler scheduler]更换为[RACScheduler mainThreadScheduler]
[[self.testSignal deliverOn:[RACScheduler scheduler]] subscribeNext:^(id x) {
NSLog(@"receiveSignal%@",[NSThread currentThread]);
}];
********打印结果*********
2016-09-02 09:48:59.697 Signal processing[1686:22894] sendTestSignal<NSThread: 0x7fb373c0bb80>{number = 1, name = main}
2016-09-02 09:48:59.697 Signal processing[1686:24680] receiveSignal<NSThread: 0x7fb373e07070>{number = 3, name = (null)}
subscribeOn则会将传递内容和副作用一起放到指定线程执行
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"sendSignal%@",[NSThread currentThread]);
[subscriber sendNext:@1];
return [RACDisposable disposableWithBlock:^{
}];
}] subscribeOn:[RACScheduler scheduler]] subscribeNext:^(id x) {
NSLog(@"receiveSignal%@",[NSThread currentThread]);
}];
**********打印结果*********
2016-09-02 09:54:47.819 Signal processing[1778:54504] sendSignal<NSThread: 0x7fde7adb4e00>{number = 2, name = (null)}
2016-09-02 09:54:47.819 Signal processing[1778:54504] receiveSignal<NSThread: 0x7fde7adb4e00>{number = 2, name = (null)}
RACChannelTo
RACChannelTo(self, name) = RACChannelTo(self.model, name);
这是一个双向绑定,self.name和self.model.name任何一个改变,另外一个也会改变
写在最后。
不断学习不断进步,如有差错,望指出,共同学习
网友评论