美文网首页
02_读书笔记_RAC中的RACSignal

02_读书笔记_RAC中的RACSignal

作者: Mark_Liu_JS | 来源:发表于2018-08-06 10:58 被阅读0次

    了解几个概念

    • 通过RACSignal创建一个信号 (默认是 冷信号)
    • 通过订阅者订阅这个信号!(变成 热信号)
    • RACSubscriber(协议):订阅者(发送信号)
    • RACDisposable:它可以帮助我们取消订阅
      • 默认一个信号发送数据完毕就会主动取消订阅
      • 只要订阅者在,就不会自动取消订阅

    基本使用的代码样例

    #import "ViewController.h"
    #import <ReactiveObjC/ReactiveObjC.h>
    
    @interface ViewController ()
    
    /// 订阅者
    @property (strong, nonnull, nonatomic) id<RACSubscriber> subscriber;
    
    @end
    
    @implementation ViewController
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
     
        // 1.创建信号(这是一个冷信号)
        // didSubscribe调用:只要一个信号被订阅就会调用!
        // didSubscribe作用:利用subscriber发送数据!
    
     __weak typeof(self) weakSelf = self;
    
        RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSLog(@"come here");
            
            // 3.发送信号
            [subscriber sendNext:@"RAC的RACSignal"];
            
            // 引用订阅者, 防止自动取消订阅
            weakSelf.subscriber = subscriber;r = subscriber;
            
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"信号取消订阅, 释放资源");
            }];
        }];
        
        // 2.订阅信号(冷信号 -> 热信号)
        // nextBlock调用:只要订阅者 发送数据 就会调用!
        // nextBlock作用: 处理数据, 展示UI界面等!
        RACDisposable *disposaable = [signal subscribeNext:^(id  _Nullable x) {
           
            // 信号中的内容
            NSLog(@"信号中发内容是: %@", x);
            
        }];
        
        // 注意: 默认一个信号发送数据完毕就会主动取消订阅
        // 只要订阅者在,就不会自动取消订阅
        // 手动取消订阅
        [disposaable dispose];
    }
    
    @end
    

    过程分析

    RACSignal.png
    • 信号的创建
    // RACSignal
    // 信号创建
    + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
        return [RACDynamicSignal createSignal:didSubscribe];
    }
    
    // 这个方法的底层是如下的实现
    //  RACDynamicSignal
    /*
        这个方法做了两件事情:
            1> 创建信号 signal
            2> 将方法中的 didSubscribe 参数 进行保存
    */
    
    // RACDynamicSignal
    // The block to invoke for each subscriber.
    @property (nonatomic, copy, readonly) RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber);
    
    + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
        RACDynamicSignal *signal = [[self alloc] init];
        
        // 保存  didSubscribe
        signal->_didSubscribe = [didSubscribe copy];
        
        return [signal setNameWithFormat:@"+createSignal:"];
    }
    
    • 信号的订阅
    // RACSignal
    /*
        订阅信号也做了两件事
            1> 创建订阅者  RACSubscriber *o
                在内部 保存了 nextBlock
                    
            2> 订阅信号     
    */ 
    - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
        NSCParameterAssert(nextBlock != NULL);
    
        // 创建一个真正的订阅者
        RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
        
        // 订阅信号 
        return [self subscribe:o];
    }
    
    //  RACSubscriber ==== 创建订阅者 
    
    // These callbacks should only be accessed while synchronized on self.
    @property (nonatomic, copy) void (^next)(id value);
    @property (nonatomic, copy) void (^error)(NSError *error);
    @property (nonatomic, copy) void (^completed)(void);
    
    // 创建订阅者
    + (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;
    }
    
    // RACDynamicSignal 
    // 订阅信号
    - (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
        NSCParameterAssert(subscriber != nil);
    
        RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
        subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
    
        if (self.didSubscribe != NULL) {
            RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
                
                // 执行 创建信号时保存的 didSubscribe  -> 回到测试代码
                RACDisposable *innerDisposable = self.didSubscribe(subscriber);
                
                [disposable addDisposable:innerDisposable];
            }];
    
            [disposable addDisposable:schedulingDisposable];
        }
        
        return disposable;
    }
    
    • 信号的发送
    // 上一步,中代码会执行我们创建信号时的 didSubscribe
    // 在源代码中, 我们进行了发送信号的操作
    // 它的内部 其它是在执行订阅者中的处理
    
    // RACSubscriber
    - (void)sendNext:(id)value {
        @synchronized (self) {
            void (^nextBlock)(id) = [self.next copy];
            if (nextBlock == nil) return;
    
            nextBlock(value); // 执行源代码中的回调处理UI等等.
        }
    }
    

    相关文章

      网友评论

          本文标题:02_读书笔记_RAC中的RACSignal

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