RAC使用及解析

一、基础使用

RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    [subscriber sendNext:@"🏀🏀🏀"];
    [subscriber sendCompleted];
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"销毁了");
    }];
}];

[signal subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@",x);
} error:^(NSError * _Nullable error) {
    
} completed:^{
    
}];

二、源码解析

RAC源码解析

三、常用类

1.RACSubject

可发送信号也可以订阅信号

    RACSubject *subject = [RACSubject subject];//继承RACSignal
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    [subject sendNext:@"🏀🏀🏀"];

RACSubject继承于RACSignal,它初始化的时候新建了一个_subscribers数组,subscribeNext的时候新建的RACPassthroughSubscriber就保存在这个数组里,sendNext的时候实际上就是数组里的RACPassthroughSubscriber在调用sendnext,所以它既能发送信号,又能订阅信号。

2.RACTuple,RACSequence

RACTuple *tuple = [RACTuple tupleWithObjects:@"1",@"2",@6,nil];
    [tuple.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        //        NSLog(@"%@",x);
    }];
NSArray *arr = @[@"1", @"2", @8];
RACSequence *sequence = arr.rac_sequence;
RACSignal *signal = sequence.signal;
[signal subscribeNext:^(id  _Nullable x) {
    //        NSLog(@"%@",x);
}];
 NSDictionary *dict = @{@"1":@"a",@"2":@"b"};
    [dict.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);//RACTuple
    }];

对数组、字典等的封装,可用于集合的遍历

3.RACMulticastConnection

用于当一个信号,被多次订阅时

RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"篮球block");
        [subscriber sendNext:@"🏀🏀🏀"];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"销毁了");
        }];
    }];
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@1",x);
    }];
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@2",x);
    }];
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@3",x);
    }];

打印

篮球block
🏀🏀🏀1
 销毁了
篮球block
 🏀🏀🏀2
 销毁了
 篮球block
 🏀🏀🏀3
 销毁了

RACSignal每一次被订阅,初始化创建的block都会被调用一次,比如这个block里面进行一个网络请求,每一次订阅的时候都要进行一次网络请求,这显然是不合理的,这时候就要用到RACMulticastConnection

https://www.jianshu.com/p/b94a0454e582

RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"篮球block1");
        [subscriber sendNext:@"🏀🏀🏀1"];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"销毁了1");
        }];
    }];
    RACMulticastConnection *connection = [signal1 publish];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@1",x);
    }];
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@2",x);
    }];
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@3",x);
    }];
    [connection connect];

看下RACSignal的publish方法

- (RACMulticastConnection *)publish {
	RACSubject *subject = [[RACSubject subject] setNameWithFormat:@"[%@] -publish", self.name];
	RACMulticastConnection *connection = [self multicast:subject];
	return connection;
}
- (RACMulticastConnection *)multicast:(RACSubject *)subject {
	[subject setNameWithFormat:@"[%@] -multicast: %@", self.name, subject.name];
	RACMulticastConnection *connection = [[RACMulticastConnection alloc] initWithSourceSignal:self subject:subject];
	return connection;
}

返回一个RACMulticastConnection,它初始化的时候保存了RACSignal和新建的RACSubject,所以后面订阅的是这个RACSubject,不会马上触发RACSignal新建的时候传入的block。
最后看下RACMulticastConnection的connect方法

- (RACDisposable *)connect {
	BOOL shouldConnect = OSAtomicCompareAndSwap32Barrier(0, 1, &_hasConnected);

	if (shouldConnect) {
		self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
	}

	return self.serialDisposable;
}

触发前面提到的block

4.RACCommand

监听执行状态

NSString *input = @"执行";
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        NSLog(@"input-->%@",input);
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [subscriber sendNext:@"🍺🍺🍺🍺🍺🍺🍺"];
            [subscriber sendError:[NSError errorWithDomain:@"error" code:-1 userInfo:nil]];
            //            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"signal销毁了");
            }];
        }];
    }];
    [command.executionSignals subscribeNext:^(RACSignal   * _Nullable x) {
        NSLog(@"executionSignals-->%@",x);
        [x subscribeNext:^(id  _Nullable x) {
            NSLog(@"executionSignals-->subscribeNext-->%@",x);
        }];
    }];
    [[command.executionSignals switchToLatest] subscribeNext:^(id  _Nullable x) {
        NSLog(@"switchToLatest-->%@",x);
    }];
    [command.executing subscribeNext:^(id  _Nullable x) {
        NSLog(@"executing-->%@",x);
    }];
    [command.errors subscribeNext:^(id  _Nullable x) {
        NSLog(@"errors-->%@",x);
    }];
    //开始执行
    [command execute:input];
[command.executing subscribeNext:^(id  _Nullable x) {
        NSLog(@"executing-->%@",x);
    }]

返回1是正在执行,0是执行完成

结合ui控件

1.UITextField

[[_myField rac_textSignal]subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"text-%@",x);
    }];

返回的是textfield的文本

  [[_myField rac_signalForControlEvents:UIControlEventEditingChanged]subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"valuechange-%@",x);
    }];

返回的是textfield本身

2.UIButton

[[self.aBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"按钮点击");
    }];

其他用法

1.替换代理

[[view rac_signalForSelector:@selector(btnClick:)]subscribeNext:^(RACTuple * _Nullable x) {
    NSLog(@"%@",x);
}];

2.替换kvo

  [RACObserve(self, tag) subscribeNext:^(id  _Nullable x) {
        NSLog(@"tag is%@",x);
    }];
    [[self rac_valuesForKeyPath:@"tag" observer:self] subscribeNext:^(id  _Nullable x) {
        NSLog(@"tag is%@",x);
    }];
    
    self.tag = 4;
    self.tag = 5;

3.替换通知

  [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"notifiTest" object:nil]subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"通知%@",x.userInfo);
    }];

4.定时器

  __block int count = 0;
    @weakify(self)
    self.disposable = [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]]subscribeNext:^(NSDate * _Nullable x) {
        @strongify(self)
        count ++;
        if (count == 10) {
            [self.disposable dispose];
        }
        NSLog(@"count %d",count);
    }];

5.延时delay

 [[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@"延迟两秒"];
        return nil;
    }] delay:2]subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

操作符

1.rac_liftSelector withSignalsFromArray

当信号组中每一个信号都至少一次sendNext之后

2.skip

跳跃前面几个信号值

3.take

指定拿前面的哪几条数据!(从前往后)

RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@"signal1 - 🏀🏀🏀"];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"signal1 - 销毁了");
        }];
    }];

    RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@"signal2 - 🏀🏀🏀"];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"signal2 - 销毁了");
        }];
    }];

4.concat

连接信号 有顺序的接收

    RACSignal *signal3 = [signal1 concat:signal2];
    [signal3 subscribeNext:^(id  _Nullable x) {
        NSLog(@"signal3 - %@",x);
    }];

先接收signal1再接收signal2

5.then

连接信号,只返回第二个信号的值,而且得等第一个信号完成之后

    RACSignal *signal3 =  [signal1 then:^RACSignal * _Nonnull{
        return signal2;
    }];
    
    [signal3 subscribeNext:^(id  _Nullable x) {
        NSLog(@"signal3 -%@",x);
    }];

6.merge

连接信号 不考虑顺序 有信号sendNext就会返回

RACSignal *signal3 =  [signal1 merge:signal2];
[signal3 subscribeNext:^(id  _Nullable x) {
        NSLog(@"signal3 -%@",x);
        }];

7.combineLatestWith

合并信号,接收最新的值(signal1),并且两个信号都要执行过sendNext,返回 RACTuple

    RACSignal *signal3 = [signal1 combineLatestWith:signal2];
    [signal3 subscribeNext:^(id  _Nullable x) {
        NSLog(@"signal3 - %@",x);
    }];

signal3返回的x值为RACTuple,集合

8.zip

把两个信号压缩成一个信号,只有当两个信号都发出信号内容时,才会触发 返回 RACTuple

    RACSignal *signal3 = [signal1 zipWith:signal2];
    [signal3 subscribeNext:^(id  _Nullable x) {
        NSLog(@"signal3 - %@",x);
    }];

9.reduce

聚合 – 把多个信号的值按照自定义的组合返回

    RACSignal *signal3 =  [RACSignal combineLatest:@[signal1, signal2] reduce:^id (NSString *s1,NSString *s2){
            return [NSString stringWithFormat:@"%@ %@",s1,s2];
    }];
    
    [signal3 subscribeNext:^(id  _Nullable x) {
        NSLog(@"signal3 -%@",x);
    }];

打印signal3 -signal1 - 🏀🏀🏀 signal2 - 🏀🏀🏀

10.flatmap和map

映射

[[_myField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            [subscriber sendNext:[NSString stringWithFormat:@"🍺%@",value]];
            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^{
                
            }];
        }];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"value:%@",x);
    }];

用bind实现的

 [[_myField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
        return [NSString stringWithFormat:@"🍺%@",value];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"value:%@",x);
    }];

用flatmp实现的

11.filter

– 过滤

[[_myField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length < 10;
    }] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"value:%@",x);
    }];

12.ignore

– 忽略

[[_myField.rac_textSignal ignore:@"123"]subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"value:%@",x);
    }];

13.distinctUntilChanged

-忽略相同

RACSubject *subject = [RACSubject subject];
    [[subject distinctUntilChanged]subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    [subject sendNext:@"123"];
    [subject sendNext:@"123"];
    [subject sendNext:@"🍺🍺"];

打印
123
🍺🍺
有改变的时候才会打印

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值