美文网首页
RAC的bind:方法

RAC的bind:方法

作者: 高思阳 | 来源:发表于2019-05-15 17:15 被阅读0次
    RACSignal *originSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@1];
        return nil;
    }];
    
    RACSignal *newSignal = [originSignal bind:^RACSignalBindBlock _Nonnull{
        RACSignalBindBlock bindingBlock = ^RACSignal *(NSNumber *value,BOOL *stop){
            value = @(value.integerValue * 2);
            return [RACSignal return:value];
        };
        return bindingBlock;
    }];
        
    [newSignal subscribeNext:^(id  _Nullable x) {
        //newSignal的订阅block
    }];
    
    //简化return方法,这个方法是生成一个RACReturnSignal对象,然后把传进来参数value保存进对象对应的_value实例变量中,然后返回这个对象
    + (RACSignal *)return:(id)value {
        RACReturnSignal *signal = [[self alloc] init];
        signal->_value = value;
        return signal;
    }
    

    RACReturnSignal中的subscribeNext:方法,以及点进去查看RACSubscriptionSchedulerschedule:方法:

    - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
        NSCParameterAssert(subscriber != nil);
    
        return [RACScheduler.subscriptionScheduler schedule:^{
            [subscriber sendNext:self.value];
            [subscriber sendCompleted];
        }];
    }
    
    - (RACDisposable *)schedule:(void (^)(void))block {
        NSCParameterAssert(block != NULL);
    
        if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block];
    
        block();//这里直接执行了上面schedule方法后面的block
        return nil;
    }
    
    - (RACSignal *)bind:(RACSignalBindBlock (^)(void))block {
        NSCParameterAssert(block != NULL);//(1)判空操作
    
        return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
    
            //(2)这里可以看出上面那个block参数,返回的应该是一个RACSignalBindBlock,所以我们使用bind的时候可以进行逆向推导
            RACSignalBindBlock bindingBlock = block(); 
            __block volatile int32_t signalCount = 1;   // indicates self
    
            RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
    
            void (^completeSignal)(RACDisposable *) = ^(RACDisposable *finishedDisposable) {
                if (OSAtomicDecrement32Barrier(&signalCount) == 0) {
                    [subscriber sendCompleted];
                    [compoundDisposable dispose];
                } else {
                    [compoundDisposable removeDisposable:finishedDisposable];
                }
            };
    
            void (^addSignal)(RACSignal *) = ^(RACSignal *signal) {
                OSAtomicIncrement32Barrier(&signalCount);
    
                RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init];
                [compoundDisposable addDisposable:selfDisposable];
    
                //(6)查看RACReturnSignal中subscribeNext:方法,会直接调用[subscriber sendNext:self.value],然后这里的block就开始执行
                RACDisposable *disposable = [signal subscribeNext:^(id x) {
                    //(7)正常情况下执行这里,这里的subscriber是新生成的RACSignal,也就是上面newSignal的订阅block
                    [subscriber sendNext:x];
                } error:^(NSError *error) {
                    [compoundDisposable dispose];
                    [subscriber sendError:error];
                } completed:^{
                    @autoreleasepool {
                        completeSignal(selfDisposable);
                    }
                }];
    
                selfDisposable.disposable = disposable;
            };
    
            @autoreleasepool {
                RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init];
                [compoundDisposable addDisposable:selfDisposable];
    
                //(3)这里是订阅原始信号originSignal,会执行originSignal的didSubscribe block,
                //执行[subscriber sendNext:@1];的时候,内部会调用下面这个subscribeNext:方法后面的block
                RACDisposable *bindingDisposable = [self subscribeNext:^(id x) {
                    // Manually check disposal to handle synchronous errors.
                    if (compoundDisposable.disposed) return;
    
                    BOOL stop = NO;
                    //(4)这里通过最开始传进来的block执行后返回的bindingBlock,得到一个RACReturnSignal对象
                    id signal = bindingBlock(x, &stop); 
                    @autoreleasepool {
                        if (signal != nil) addSignal(signal); // (5) 执行上面的addSignal block块
                        if (signal == nil || stop) {
                            [selfDisposable dispose];
                            completeSignal(selfDisposable);
                        }
                    }
                } error:^(NSError *error) {
                    [compoundDisposable dispose];
                    [subscriber sendError:error];
                } completed:^{
                    @autoreleasepool {
                        completeSignal(selfDisposable);
                    }
                }];
    
                selfDisposable.disposable = bindingDisposable;
            }
    
            return compoundDisposable;
        }] setNameWithFormat:@"[%@] -bind:", self.name];
    }
    

    相关文章

      网友评论

          本文标题:RAC的bind:方法

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