美文网首页
03_读书笔记_RAC中的RACSubject

03_读书笔记_RAC中的RACSubject

作者: Mark_Liu_JS | 来源:发表于2018-08-06 12:36 被阅读0次
  • RACSubject :信号提供者,自己可以充当信号,又能够发送信号
@interface RACSubject<ValueType> : RACSignal<ValueType> <RACSubscriber>

/// Returns a new subject.
+ (instancetype)subject;

// Redeclaration of the RACSubscriber method. Made in order to specify a generic type.
- (void)sendNext:(nullable ValueType)value;

@end

基本使用


#import "ViewController.h"
#import <ReactiveObjC/ReactiveObjC.h>

@interface ViewController ()

@end

@implementation ViewController


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    // 1.订阅信号
    RACSubject *subject = [RACSubject subject];
    
    // 2.订阅信号
    // 不同的信号,订阅方式不一样(因为类型不一样,所以调用方法不一样)
    [subject subscribeNext:^(id  _Nullable x) {
       
        NSLog(@"第1个订阅信号中的内容是: %@", x);
    }];
    
    [subject subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"第2个订阅信号中的内容是: %@", x);
    }];
    
    [subject subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"第3个订阅信号中的内容是: %@", x);
    }];
    
    // 3.发送信号
    // 遍历出所有的订阅者,调用nextBlock
    [subject sendNext:@"subject的信号"];
}

过程分析

RACSubject.png
  • 创建信号
// RACSubject
// 创建一个容量为1的数组
+ (instancetype)subject {
    return [[self alloc] init];
}

- (instancetype)init {
    self = [super init];
    if (self == nil) return nil;

    _disposable = [RACCompoundDisposable compoundDisposable];
    _subscribers = [[NSMutableArray alloc] initWithCapacity:1];
    
    return self;
}
  • 订阅信号
// RACSignal
// 订阅信号 调用父类的方法 RACSignal 
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    
    // 创建订阅者    在内部 保存了 nextBlock
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    
    return [self subscribe:o]; // 注意此时的 self 是 RACSubject
}

// RACSubject
// 保存订阅者

// This should only be used while synchronized on `self`.
@property (nonatomic, strong, readonly) NSMutableArray *subscribers;


- (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];
    }
    
    [disposable addDisposable:[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];
        }
    }]];

    return disposable;
}
  • 发送信号
// RACSubject 

// This should only be used while synchronized on `self`.
@property (nonatomic, strong, readonly) NSMutableArray *subscribers;

// 遍历每个一个订阅都 进行逐一发送消息
- (void)enumerateSubscribersUsingBlock:(void (^)(id<RACSubscriber> subscriber))block {
    NSArray *subscribers;
    @synchronized (self.subscribers) {
        subscribers = [self.subscribers copy];
    }

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

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

// RACSubscriber
- (void)sendNext:(id)value {
    @synchronized (self) {
        void (^nextBlock)(id) = [self.next copy];
        if (nextBlock == nil) return;

        nextBlock(value);
    }
}

相关文章

  • 03_读书笔记_RAC中的RACSubject

    RACSubject :信号提供者,自己可以充当信号,又能够发送信号 基本使用 过程分析 创建信号 订阅信号 发送信号

  • RAC+MVVM 用法大全

    RAC+MVVM在实际开发中的常用用法 RACSignal RACSubject RACSubject 在使用中我...

  • RAC中的RACSubject

    rac中热信号的源头,继承于RACSignal用法比较简单,如下: 看log可以看出racsubject和racs...

  • RAC - RACSubject

    RACSubject :信号提供者,自己可以充当信号,又能发送信号。 使用场景:通常用来代替代理,实现传值 RAC...

  • RAC框架源码解析之RACSubject的使用场景一

    1、RACSubject的运用场景 前面说到RACSubject既能 订阅信号 又能 发送信号 ,RAC可以代替我...

  • ReactiveCocoa(3)高级用法

    这篇主要运用RACSubject 先复习下第一篇中说到的RACSubject,话不多说,上来就是RAC三部曲 OK...

  • RAC简单介绍

    RAC在iOS的实际开发中确实是一件有力的武器,此文将从以下几方面讲解 RACSignal RACSubject ...

  • RAC_2.RACSubject

    2. RACSubject 使用场景:通常用来代替代理,有了它,就不必要定义代理了。 示例代码: 实际应用 JJV...

  • 04RAC-RACSubject

    我们完全可以用RACSubject代替代理/通知,确实方便许多 点击第二个控制的按钮,返回第一个控制器,并将“po...

  • iOS RAC - RACSubject、RACReplaySu

    文章系列《RACSignal 》《RACDisposable》《RACSubject、RACReplaySubje...

网友评论

      本文标题:03_读书笔记_RAC中的RACSubject

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