了解几个概念
- 通过RACSignal创建一个信号 (默认是 冷信号)
- 通过订阅者订阅这个信号!(变成 热信号)
- RACSubscriber(协议):订阅者(发送信号)
- RACDisposable:它可以帮助我们取消订阅
- 默认一个信号发送数据完毕就会主动取消订阅
- 只要订阅者在,就不会自动取消订阅
基本使用的代码样例
#import "ViewController.h"
#import <ReactiveObjC/ReactiveObjC.h>
@interface ViewController ()
/// 订阅者
@property (strong, nonnull, nonatomic) id<RACSubscriber> subscriber;
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.创建信号(这是一个冷信号)
// didSubscribe调用:只要一个信号被订阅就会调用!
// didSubscribe作用:利用subscriber发送数据!
__weak typeof(self) weakSelf = self;
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"come here");
// 3.发送信号
[subscriber sendNext:@"RAC的RACSignal"];
// 引用订阅者, 防止自动取消订阅
weakSelf.subscriber = subscriber;r = subscriber;
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号取消订阅, 释放资源");
}];
}];
// 2.订阅信号(冷信号 -> 热信号)
// nextBlock调用:只要订阅者 发送数据 就会调用!
// nextBlock作用: 处理数据, 展示UI界面等!
RACDisposable *disposaable = [signal subscribeNext:^(id _Nullable x) {
// 信号中的内容
NSLog(@"信号中发内容是: %@", x);
}];
// 注意: 默认一个信号发送数据完毕就会主动取消订阅
// 只要订阅者在,就不会自动取消订阅
// 手动取消订阅
[disposaable dispose];
}
@end
过程分析
// RACSignal
// 信号创建
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
return [RACDynamicSignal createSignal:didSubscribe];
}
// 这个方法的底层是如下的实现
// RACDynamicSignal
/*
这个方法做了两件事情:
1> 创建信号 signal
2> 将方法中的 didSubscribe 参数 进行保存
*/
// RACDynamicSignal
// The block to invoke for each subscriber.
@property (nonatomic, copy, readonly) RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber);
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
RACDynamicSignal *signal = [[self alloc] init];
// 保存 didSubscribe
signal->_didSubscribe = [didSubscribe copy];
return [signal setNameWithFormat:@"+createSignal:"];
}
// RACSignal
/*
订阅信号也做了两件事
1> 创建订阅者 RACSubscriber *o
在内部 保存了 nextBlock
2> 订阅信号
*/
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
NSCParameterAssert(nextBlock != NULL);
// 创建一个真正的订阅者
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
// 订阅信号
return [self subscribe:o];
}
// RACSubscriber ==== 创建订阅者
// These callbacks should only be accessed while synchronized on self.
@property (nonatomic, copy) void (^next)(id value);
@property (nonatomic, copy) void (^error)(NSError *error);
@property (nonatomic, copy) void (^completed)(void);
// 创建订阅者
+ (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed {
RACSubscriber *subscriber = [[self alloc] init];
subscriber->_next = [next copy]; // 保存
subscriber->_error = [error copy];
subscriber->_completed = [completed copy];
return subscriber;
}
// RACDynamicSignal
// 订阅信号
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
NSCParameterAssert(subscriber != nil);
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
if (self.didSubscribe != NULL) {
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
// 执行 创建信号时保存的 didSubscribe -> 回到测试代码
RACDisposable *innerDisposable = self.didSubscribe(subscriber);
[disposable addDisposable:innerDisposable];
}];
[disposable addDisposable:schedulingDisposable];
}
return disposable;
}
// 上一步,中代码会执行我们创建信号时的 didSubscribe
// 在源代码中, 我们进行了发送信号的操作
// 它的内部 其它是在执行订阅者中的处理
// RACSubscriber
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value); // 执行源代码中的回调处理UI等等.
}
}