RAC基础

作者: 夜沐月 | 来源:发表于2020-08-05 20:37 被阅读0次

    RAC是一套基于Cocoa的FRP框架,它的优点是用户的输入转化为随时间改变的函数,取消了可变状态.在RAC的世界里,"万物"皆为信号,一个基础的信号创建,订阅,发送,销毁过程简单的可以用一下代码表示

     // 创建信号时传递参数block:由 返回值RACDisposable   参数subscriber  代码块组成
    
       @weakify(self);
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *  _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
      @strongify(self);
            // block代码块 会在信号订阅方法subscribeNext调用的时候执行
            [subscriber sendNext:@"RAC"];
            // 如果不再发送数据,最好发送信号完成,内部会自动调用[RACDisposable disposable]取消订阅信号。
              [subscriber sendCompleted];
            NSLog(@"subscriber == %@",subscriber);
            RACDisposable *disposable = [RACDisposable disposableWithBlock:^{
                // 销毁信号
                // block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号。
                // 执行完Block后,当前信号就不在被订阅了。
                NSLog(@"开始销毁");
            }];
            return disposable;
            
        }];
        // 订阅信号,才会激活信号.
        [signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"x == %@",x);
        }];
    

    RAC的奇妙之处在于使用Block作为参数,Block可以封装了函数调用以及函数调用环境,然后在需要的地方调用.
    当我们调用createSignal创建信号时,方法执行调用

    RACDynamicSignal : 使用块实现其订阅行为的私有“RACSignal”子类
    + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
        RACDynamicSignal *signal = [[self alloc] init];
        signal->_didSubscribe = [didSubscribe copy];
        return [signal setNameWithFormat:@"+createSignal:"];
    }
    

    此时产生信号,并用信号保存每个订阅者要调用的块.
    创建信号后,调用订阅信号subscribeNext会执行

    RACSubscriber
    + (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed {
        RACSubscriber *subscriber = [[self alloc] init];
    
        subscriber->_next = [next copy];
        subscriber->_error = [error copy];
        subscriber->_completed = [completed copy];
    
        return subscriber;
    }
    

    创建订阅者,并用属性保存订阅者Block,之后调用[self subscribe:o]

    self是创建信号时的RACDynamicSignal所以调用[self subscribe:o]执行以下 这里类似类簇的应用
    - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
        NSCParameterAssert(subscriber != nil);
    
        RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
    //subscriber用属性保存subscriber,用于在[subscriber sendNext:@"RAC"]执行时,调用[self.innerSubscriber sendNext:value]
        subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
    
        if (self.didSubscribe != NULL) {
            RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
                RACDisposable *innerDisposable = self.didSubscribe(subscriber);
                [disposable addDisposable:innerDisposable];
            }];
    
            [disposable addDisposable:schedulingDisposable];
        }
        
        return disposable;
    }
    
    

    此时创建销毁者RACCompoundDisposable, RACPassthroughSubscriber当不被销毁时将所有事件传递给另一个订阅者的私有订阅者.如果每个订阅者要调用的块didSubscribe存在,创建RACScheduler(调度者用于控制何时何地执行工作)的子类RACSubscriptionScheduler(仅用于订阅的私有调度者),默认主线程执行block,调用self.didSubscribe(subscriber)

    - (RACDisposable *)schedule:(void (^)(void))block {
        NSCParameterAssert(block != NULL);
    
        if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block];
    
        block();
        return nil;
    }
    

    接着将返回didSubscribe初始化的地方createSignal:
    当调用 [subscriber sendNext:@"RAC"];时会执行

    subscriber 为前面RACPassthroughSubscriber  也是应用类簇
    - (void)sendNext:(id)value {
        if (self.disposable.disposed) return;
    
        if (RACSIGNAL_NEXT_ENABLED()) {
            RACSIGNAL_NEXT(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description), cleanedDTraceString([value description]));
        }
      
        [self.innerSubscriber sendNext:value];
    }
    

    此时[self.innerSubscriber sendNext:value];便触发订阅者的block调用

      [signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"x == %@",x);
        }];
    

    这样一个简单的信号创建,订阅,发送,销毁过程就结束了,整个过程应用类簇和block实现FRP
    除了上述模式创建信号你也可以这样

    RACReturnSignal
    // 一个私有的“RACSignal”子类,它同步向任何订阅者发送信号,然后完成
     [[RACSignal return:@"123456"] subscribeNext:^(id  _Nullable x) {
            NSLog(@"-----%@",x);
        }];
    
    RACErrorSignal
    一个私有的“RACSignal”子类,它同步向任何订阅者
     RACSignal *signal = [RACSignal error:[NSError errorWithDomain:@"" code:404 userInfo:nil]];
        [signal subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@",x);
        }];
    
    

    不同的信号用不同的子类创建,同时存储不同的属性

    冷热信号

    热信号 : 是主动的,即时没有订阅,它也会源源不断的推送,它可以有多个订阅者是一对多,集合与订阅者共享信息.
    冷信号: 是被动的,每个订阅都是独立行为.每一订阅都会执行一次.

    相关文章

      网友评论

        本文标题:RAC基础

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