RACSignal、RACSubject、RACReplaySubject
- RACSignal
// **1. 创建信号**
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
// 该block,只要该信号被订阅就会调用;主要用于发送数据
// **3. 发送数据**
[subscriber sendNext:@"123456"];
// **3.1. 数据发送完毕**
[subscriber sendCompleted];
// 通常这里可以用 return nil;代替
return [RACDisposable disposableWithBlock:^{
// 只要信号取消订阅,就会调用该block;主要用于清空资源
// **4.1. 清空资源**
NSLog(@"信号资源被清空!");
}];
}];
// **2. 订阅信号**
RACDisposable *disposable = [signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
// **4. 调用清空资源**
[disposable dispose];
RACSubject
// **1. 创建信号**
RACSubject *subject = [RACSubject subject];
// **2. 订阅信号**
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
// **3. 发送数据**
[subject sendNext:@"数据"];RACReplaySubject
// **1. 创建信号**
RACReplaySubject *subject = [RACReplaySubject subject];
// **2. 订阅信号**
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
// **3. 发送数据**
// 在RACReplaySubject中,可以在订阅信号之前发送数据;
// 而,RACSubject则不行
[subject sendNext:@"replay"];
注意:
1. RACSubscriber:表示订阅者,用于发送信号,这是一个协议,不是一个类,只要遵守该协议,并实现相应方法才能成为订阅者。通过create创建信号,都有一个订阅者,帮助它发送数据。
2. RACDisposable:用于取消订阅或者清理资源,当信号发送完成或者发送错误时,就会自动触发。
:不想监听某个信号时,可以通过它主动取消订阅信号。
3. RACSubject:信号提供者,自己可以充当信号,又能发送信号。(可以代替代理)
4. RACReplaySubjet:重复提供信号类,(RACSubject子类)。
:RACReplaySubject与RACSubject的区别,RACReplaySubject可以先发送信号,再订阅信号;RACSubject就不可以。
:如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复提供信号类。
:可以设置capacity数量来限制缓存的value的数量,即只缓存最新的几个值。
使用RACSubject替代代理的实现
- WDYRedView.h
@interface WDYRedView : UIView
@property (nonatomic, strong) RACSubject *signalSubject;
@end- WDYRedView.m
@implementation WDYRedView
(RACSubject *)signalSubject {
if (_signalSubject == nil) { _signalSubject = [RACSubject subject];}
return _signalSubject;
}
(void)clickView:(UITapGestureRecognizer *)gesture {
[self.signalSubject sendNext:@”点击了View视图”];
}
(void)layoutSubviews {
[super layoutSubviews];
[self setBackgroundColor:[UIColor redColor]];
[self setUserInteractionEnabled:YES];
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickView:)]];
}
@end- 控制器中调用(点击后传值)
// RACSubject代替代理的实现 -> 可以传值
WDYRedView *redView = [[WDYRedView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:redView];
[redView.signalSubject subscribeNext:^(id _Nullable x) {
NSLog(@”%@”, x);
}];