RAC初窥

作者: 952625a28d0d | 来源:发表于2017-04-21 00:31 被阅读59次

    先预习一下Block

    • Block
    inlineBlock```
    
    

    <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
    <#statements#>
    };```

    /**
     *  Block : ARC strong 使用strong就可以 但是非ARC就用copy
     */
    @property (nonatomic, copy) void(^JYFBlock)();```
    
    

    // 1.对象里面包含一个属性 Block作为对象的属性
    self.p = [[Person alloc] init];

    // Block --inlineBlock
    void(^JYFBlock)() = ^() {
        NSLog(@"发哥");
    };
    
    self.p.JYFBlock = JYFBlock;
    
    
    
    • (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
      self.p.JYFBlock();
      }
    
    -     作为参数传递
    
    
    • (void)eat:(void(^)(NSString *))block;```
    - (void)eat:(void (^)(NSString *))block{
        block(@"香蕉");
    }
    
    // 作为参数传递
        self.p = [[Person alloc] init];
        [self.p eat:^(NSString *value){
            NSLog(@"%@", value);
        }];```
    
        // 只要有返回值的方法 我们都可以使用点语法 那么Get方法之所以能点 就是因为有返回值
    
    - Block作为返回值(扩展非常强!!!)
    
    

    // 定义一个能够返回Block的Run方法

    • (void(^)(int))run;```
    - (void (^)(int))run{
        return ^(int m){
            NSLog(@"哥们跑起来了 跑了%d",m);
        };
    }
    
    self.p = [[Person alloc] init];
        //p.run(3)
        self.p.run(100);```
    
    ###RAC
    - ReactiveCocoa(RAC) Github上的一个开源框架
    - RAC有什么用呢?
        1: 帮助我们更简单霸气地处理事件
        2: 函数响应编程框架
    
    
    - 1: RACSignal:信号类!通过它创建一个信号
    2:通过订阅者订阅刚刚的信号!(变成:热信号)
    3:发送信号
    
    
    

    RACSignal:信号类 当我们有数据产生的时候 我们就创建一个信号 这个Block需要一个返回值
    // 1. 创建信号(冷信号!)
    // 被订阅 就会调用
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        // 3:发送信号subscriber
        [subscriber sendNext:@"呵呵哈哈嘿嘿额"];
        
        return nil;
    }];
    
    // 2. 订阅信号(热信号!!)
    // 发动的时候才会调用
    // 处理数据 展示UI界面
    [signal subscribeNext:^(id x) {
       // 订阅信号
        // x: 信号发送的内容!!
        NSLog(@"%@",x);
    }];
    
    
    - RAC原理
    1:创建信号RACSignal,底层保存信号Block
    
    
    • (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
      RACDynamicSignal *signal = [[self alloc] init];
      signal->_didSubscribe = [didSubscribe copy];
      return [signal setNameWithFormat:@"+createSignal:"];
      }
    
    2:订阅信号 先创建一个订阅者(RACSubscriber) 然后才去订阅信号 保存了订阅者nextBlock
    
    
    • (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
      NSCParameterAssert(nextBlock != NULL);

      RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
      return [self subscribe:o];
      }```

    Paste_Image.png
    • 执行didSubscriber
    Paste_Image.png
    • 执行的时候 干了什么事情???
    • 即走进了之前的保存的Block 即发送数据
    Paste_Image.png Paste_Image.png
    • 发送消息 做了什么??

    从源码来看 终于调用了block 那么订阅者接收到了信息

    #pragma mark RACSubscriber
    
    - (void)sendNext:(id)value {
        @synchronized (self) {
            void (^nextBlock)(id) = [self.next copy];
            if (nextBlock == nil) return;
    
            nextBlock(value);
        }
    }```
    
    
    ###流程图
    
    ![Paste_Image.png](https://img.haomeiwen.com/i189984/6114db92e3f5ad7f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ###RACDisposable
    它可以帮助我们取消订阅,信号发送完毕了,或者失败了,我们都要取消订阅,就像我们注册通知,取消通知一样的道理。
    
    

    // RACSignal:信号类 当我们有数据产生的时候 我们就创建一个信号 这个Block需要一个返回值
    // 1. 创建信号(冷信号!)
    // 被订阅 就会调用
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        // 3:发送信号subscriber 默认一个信号发送完毕 就会取消完毕
        [subscriber sendNext:@"呵呵哈哈嘿嘿额"];
        
        return [RACDisposable disposableWithBlock:^{
            // 只要信号取消订阅 就回来这里
            // 为什么会来这里呢?因为消息发送完毕之后 sub就没了
            // 清空资源
            NSLog(@"哥们取消订阅了");
        }];
    }];
    
    // 2. 订阅信号(热信号!!)
    // 发动的时候才会调用
    // 处理数据 展示UI界面
    RACDisposable *disposable = [signal subscribeNext:^(id x) {
       // 订阅信号
        // x: 信号发送的内容!!
        NSLog(@"%@",x);
    }];
    
    // 手动取消订阅
    [disposable dispose];
    
    
    ###RACSubject:信号提供者!!自己可以充当信号,又能够发送信号
    

    //1:创建信号
    RACSubject *subject = [RACSubject subject];

    // 2:订阅信号
    [subject subscribeNext:^(id x) {
        NSLog(@"接收到了数据%@",x);
    }];
    // 3: 发送信号
    [subject sendNext:@"汉堡包"];```
    
    Paste_Image.png
    • 由上图可以看出 之所以RACSubject拥有这么多功能,是因为它使用继承Signal+遵守Subscriber协议。
    • 来看一下生命周期
    #pragma mark Lifecycle
    
    + (instancetype)subject {
        return [[self alloc] init];
    }
    
    - (id)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的生命周期,进行了一个维护。

    1:创建信号(RACSubject)就是创建了一个可变数组,就是我们的Subscribers

    - (id)init {
        self = [super init];
        if (self == nil) return nil;
    
        _disposable = [RACCompoundDisposable compoundDisposable];
        _subscribers = [[NSMutableArray alloc] initWithCapacity:1];
        
        return self;
    }
    

    2:订阅信号

    - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
        NSCParameterAssert(nextBlock != NULL);
        
        RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
        return [self subscribe:o];
    }```
    
    
    ![Paste_Image.png](https://img.haomeiwen.com/i189984/b90cbb851466b49d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    • (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
      NSCParameterAssert(subscriber != nil);

      RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
      subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];

    // 拿到数组
    NSMutableArray *subscribers = self.subscribers;
    @synchronized (subscribers) {
    // 将订阅者保存到数组中
    [subscribers addObject:subscriber];
    }

    return [RACDisposable disposableWithBlock:^{
        @synchronized (subscribers) {
            // Since newer subscribers are generally shorter-lived, search
            // starting from the end of the list.
            NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
                return obj == subscriber;
            }];
    
            if (index != NSNotFound) [subscribers removeObjectAtIndex:index];
        }
    }];
    

    }

    
    3:发送数据 遍历订阅者对象执行 遍历发送
    
    ![Paste_Image.png](https://img.haomeiwen.com/i189984/c396716d22f50cab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    • (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block {
      NSArray *subscribers;
      @synchronized (self.subscribers) {
      subscribers = [self.subscribers copy];
      }

      for (id<RACSubscriber> subscriber in subscribers) {
      block(subscriber);
      }
      }

    
    

    pragma mark RACSubscriber

    • (void)sendNext:(id)value {
      [self enumerateSubscribersUsingBlock:^(id<RACSubscriber> subscriber) {
      [subscriber sendNext:value];
      }];
      }```

    相关文章

      网友评论

          本文标题:RAC初窥

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