1.RACSubject:RACSubject:信号提供者,自己可以充当信号,又能发送信号。
2.使用场景:通常用来代替代理,有了它,就不必要定义代理了。
需求:
1.给当前控制器添加一个按钮,push到另一个控制器界面
2.另一个控制器view中有个按钮,点击按钮,返回控制器的第一个页面和接收到第二个界面的消息
第一个界面:
- (void)viewDidLoad {
[super viewDidLoad];
/*
// RACSubject使用步骤
// 1.创建信号 [RACSubject subject],跟RACSiganl不一样,创建信号时没有block。
// 2.订阅信号 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
// 3.发送信号 sendNext:(id)value
// RACSubject:底层实现和RACSignal不一样。
// 1.调用subscribeNext订阅信号,只是把订阅者保存起来,并且订阅者的nextBlock已经赋值了。
// 2.调用sendNext发送信号,遍历刚刚保存的所有订阅者,一个一个调用订阅者的nextBlock。
*/
self.view.backgroundColor = [UIColor whiteColor];
[self buildUI];
}
- (void)buildUI {
self.button.frame = CGRectMake(100, 100, 80, 30);
[self.view addSubview:self.button];
}
#pragma mark---lazy loading
- (UIButton *)button {
if (!_button) {
_button = [[UIButton alloc] init];
[_button setBackgroundColor:[UIColor redColor]];
[_button setTitle:@"push" forState:UIControlStateNormal];
[[_button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
TwoViewController *twoVC = [[TwoViewController alloc] init];
twoVC.subject = [RACSubject subject];
[twoVC.subject subscribeNext:^(id x) { // 这里的x便是sendNext发送过来的信号
NSLog(@"%@", x);
[self.button setTitle:x forState:UIControlStateNormal];
}];
[self.navigationController pushViewController:twoVC animated:YES];
}];
}
return _button;
}
TwoViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor brownColor];
[self buildUI];
}
- (void)buildUI {
self.button.frame = CGRectMake(50, 100, 50, 30);
self.view.backgroundColor = [UIColor purpleColor];
[self.view addSubview:self.button];
}
#pragma mark---lazy loading
- (UIButton *)button {
if (!_button) {
_button = [[UIButton alloc] init];
[_button setBackgroundColor:[UIColor grayColor]];
[_button setTitle:@"pop" forState:UIControlStateNormal];
[[_button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
[self.subject sendNext:@"ws"];
[self.navigationController popViewControllerAnimated:YES];
}];
}
return _button;
}
- 总结:
我们完全可以用RACSubject代替代理/通知,确实方便许多
这里我们点击TwoViewController的pop的时候将字符串"ws"传给了ViewController的button的title。
步骤:
// 1.创建信号
RACSubject *subject = [RACSubject subject];
// 2.订阅信号
[subject subscribeNext:^(id x) {
// block:当有数据发出的时候就会调用
// block:处理数据
NSLog(@"%@",x);
}];
// 3.发送信号
[subject sendNext:value];
注意:~~
RACSubject和RACReplaySubject的区别
RACSubject必须要先订阅信号之后才能发送信号,而RACReplaySubject可以先发送信号后订阅.
RACSubject 代码中体现为:先走TwoViewController的sendNext,后走ViewController的subscribeNext订阅
RACReplaySubject 代码中体现为:先走ViewController的subscribeNext订阅,后走TwoViewController的sendNext
可按实际情况各取所需。