之前介绍了RACSignal类以及使用方法,这次要介绍的是RACSignal的子类:RACSubject。
先看下RACSubject基本使用方法:
//1.创建信号
RACSubject *subject = [RACSubject subject];
//2.订阅信号
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
//3.发送信号
[subject sendNext:@"this is a RACSubject"];
与RACSignal父类的使用方法相比,缺省了信号销毁的方法声明。
查看RACSubject的内部实现
+ (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;
}
- (void)dealloc {
[self.disposable dispose];
}
从这就可以看出,在初始化创建RACSubject类的对象同时,创建了一个组合式销毁栈,而且在dealloc
方法中执行了组合式销毁栈的信号销毁操作,并没有和父类RACSignal一样,创建并保存了一个销毁信号的成员变量。也就是说RACSubject类是在内部通过组合式销毁栈RACCompoundDisposable
自动完成信号销毁。
那么与之对应的RACSubject与父类RACSignal的订阅、发送消息也有不同。
在RACSignal类的subscribe方法中,执行了_didSubscribe( )
代码块,也就是在创建信号时保存的成员变量didSubscribe
销毁信号,而RACSignal类的subscribe方法则是通过RACCompoundDisposable
来完成信号的销毁。下面两张图为subscribe
方法的实现对比。
接下来,该到了发送订阅消息的方法中:
- (void)sendNext:(id)value {
[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
[subscriber sendNext:value];
}];
}
- (void)sendError:(NSError *)error {
[self.disposable dispose];
[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
[subscriber sendError:error];
}];
}
- (void)sendCompleted {
[self.disposable dispose];
[self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
[subscriber sendCompleted];
}];
}
//遍历所有的订阅者信号并发送一次
- (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block {
NSArray *subscribers;
@synchronized (self.subscribers) {
subscribers = [self.subscribers copy];
}
for (id<RACSubscriber> subscriber in subscribers) {
block(subscriber);
}
}
RACSubject类中在发送信号时,RACSubject类会将所有的订阅者信号全部遍历并发送一次。除此以外,RACSubject类与父类RACSignal的发送信号流程相同:执行相应的nextBlock( )
RACSubject类是将父类RACSignal的封装,将销毁信号的管理放在内部进行自动管理实现。为了更加形象的总结描述RACSubject类的流程,附加一张简单的流程分析图
该文章首次发表在 简书:我只不过是出来写写代码 博客,并自动同步至 腾讯云:我只不过是出来写写iOS 博客