RAC(ReactiveCocoa)介绍(九)——RACSubject流程分析

之前介绍了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方法的实现对比。

RACSignal类的subscribe方法实现

RACSubject类的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类的流程,附加一张简单的流程分析图

RACSubject类流程图

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券