- RACSubject :信號(hào)提供者,自己可以充當(dāng)信號(hào),又能夠發(fā)送信號(hào)
@interface RACSubject<ValueType> : RACSignal<ValueType> <RACSubscriber>
/// Returns a new subject.
+ (instancetype)subject;
// Redeclaration of the RACSubscriber method. Made in order to specify a generic type.
- (void)sendNext:(nullable ValueType)value;
@end
基本使用
#import "ViewController.h"
#import <ReactiveObjC/ReactiveObjC.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.訂閱信號(hào)
RACSubject *subject = [RACSubject subject];
// 2.訂閱信號(hào)
// 不同的信號(hào)砚尽,訂閱方式不一樣(因?yàn)轭愋筒灰粯樱哉{(diào)用方法不一樣)
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"第1個(gè)訂閱信號(hào)中的內(nèi)容是: %@", x);
}];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"第2個(gè)訂閱信號(hào)中的內(nèi)容是: %@", x);
}];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"第3個(gè)訂閱信號(hào)中的內(nèi)容是: %@", x);
}];
// 3.發(fā)送信號(hào)
// 遍歷出所有的訂閱者,調(diào)用nextBlock
[subject sendNext:@"subject的信號(hào)"];
}
過(guò)程分析
// RACSubject
// 創(chuàng)建一個(gè)容量為1的數(shù)組
+ (instancetype)subject {
return [[self alloc] init];
}
- (instancetype)init {
self = [super init];
if (self == nil) return nil;
_disposable = [RACCompoundDisposable compoundDisposable];
_subscribers = [[NSMutableArray alloc] initWithCapacity:1];
return self;
}
// RACSignal
// 訂閱信號(hào) 調(diào)用父類的方法 RACSignal
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
NSCParameterAssert(nextBlock != NULL);
// 創(chuàng)建訂閱者 在內(nèi)部 保存了 nextBlock
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
return [self subscribe:o]; // 注意此時(shí)的 self 是 RACSubject
}
// RACSubject
// 保存訂閱者
// This should only be used while synchronized on `self`.
@property (nonatomic, strong, readonly) NSMutableArray *subscribers;
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
NSCParameterAssert(subscriber != nil);
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
NSMutableArray *subscribers = self.subscribers;
@synchronized (subscribers) {
// 保存訂閱者
[subscribers addObject:subscriber];
}
[disposable addDisposable:[RACDisposable disposableWithBlock:^{
@synchronized (subscribers) {
// Since newer subscribers are generally shorter-lived, search
// starting from the end of the list.
NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
return obj == subscriber;
}];
if (index != NSNotFound) [subscribers removeObjectAtIndex:index];
}
}]];
return disposable;
}
// RACSubject
// This should only be used while synchronized on `self`.
@property (nonatomic, strong, readonly) NSMutableArray *subscribers;
// 遍歷每個(gè)一個(gè)訂閱都 進(jìn)行逐一發(fā)送消息
- (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block {
NSArray *subscribers;
@synchronized (self.subscribers) {
subscribers = [self.subscribers copy];
}
for (id<RACSubscriber> subscriber in subscribers) {
block(subscriber);
}
}
- (void)sendNext:(id)value {
[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
[subscriber sendNext:value];
}];
}
// RACSubscriber
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value);
}
}