美文网首页
RAC中的RACReplaySubject

RAC中的RACReplaySubject

作者: 一只二进制编码的狗 | 来源:发表于2016-12-02 15:51 被阅读26次

    RACSubject的子类,说这个主要为了下篇文章,重写了RACSubject的四个个重要方法:subscribe,sendNext,sendCompleted, sendError

    - (void)sendNext:(id)value {
        @synchronized (self) {
    //用数组存了下sendNext的值
            [self.valuesReceived addObject:value ?: RACTupleNil.tupleNil];
            [super sendNext:value];
    //这个数组有个额度,当超过这个额度,就把前面的清掉。逻辑简单 
            if (self.capacity != RACReplaySubjectUnlimitedCapacity && self.valuesReceived.count > self.capacity) {
                [self.valuesReceived removeObjectsInRange:NSMakeRange(0, self.valuesReceived.count - self.capacity)];
            }
        }
    }
    
    - (void)sendCompleted {
        @synchronized (self) {
    //存下commplete的状态
            self.hasCompleted = YES;
            [super sendCompleted];
        }
    }
    
    - (void)sendError:(NSError *)e {
        @synchronized (self) {
    //存下error的状态
            self.hasError = YES;
            self.error = e;
            [super sendError:e];
        }
    }
    

    好的,这时候如果有人订阅了这个信号,看看subscribe的操作

    - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
        RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
    
        RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
            @synchronized (self) {
    //好的。如果这时候以前已经被订阅过了,那valuesReceived里面就有值了,就不需要要再走一次didsubribe了,直接sendNext了。这个还是很方便的,如果didsubribe里面有网络请求,那多次订阅不使用这个就会发很多次请求。
                for (id value in self.valuesReceived) {
                    if (compoundDisposable.disposed) return;
    
                    [subscriber sendNext:(value == RACTupleNil.tupleNil ? nil : value)];
                }
    
                if (compoundDisposable.disposed) return;
                if (self.hasCompleted) {
                    [subscriber sendCompleted];
                } else if (self.hasError) {
                    [subscriber sendError:self.error];
                } else {
    //如果没被订阅过,那就老老实实的走一次didsubscriber
                    RACDisposable *subscriptionDisposable = [super subscribe:subscriber];
                    [compoundDisposable addDisposable:subscriptionDisposable];
                }
            }
        }];
    
        [compoundDisposable addDisposable:schedulingDisposable];
    
        return compoundDisposable;
    }
    

    相关文章

      网友评论

          本文标题:RAC中的RACReplaySubject

          本文链接:https://www.haomeiwen.com/subject/sjhqmttx.html