RAC

RACSignal

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber){
    [subscriber sendNext: @1]
    
    return nil;
}];

RACSubject

作用:可以代替代理(protocol)

RACMulticastConnection

作用:解决RACSignal的副作用问题
RACSignal副作用:当多次执行 [signal subscribeNext:] 方法的时候,singal中的block就会执行多次

解决方式:
在执行 [signal subscribeNext:]之前,把RACSignal转化为RACMulticastConnection

RACMulticastConnection *connection = [signal publish];

[connection.signal subscribeNext:^(id x)({

}];

[connection.signal subscribeNext:^(id x)({

}];

//进行连接
[connection connect];

这样之后,尽管subscribeNext方法调用了两次,但是在singal中的block也只会执行一次

原理:创建一个RACSubject订阅signal

RACCommand

作用:用于处理事件的类
注意点:

1. RACCommand内部必需要返回signal 
2. executionSignals 信号中信号,一开始获取不到内部信号
    1. switchToLatest:获取最近的内部信号
    2. execute:获取内部信号
3. executing:判断是否正在执行
    1. 第一次不准确,需要skip跳过
    2. 一定要记得sendCompleted,否则永远不会执行完成
4. execute执行,执行command的block

基本使用:

    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
       
        NSLog(@"执行block");
        
        return [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
            
            [subscriber sendNext:@2];
            [subscriber sendCompleted];
            
            return nil;
        }];
        
    }];
    
    // 执行第一种方式
//    [[command execute:@1] subscribeNext:^(id  _Nullable x) {
//        NSLog(@"1111---%@", x);
//    }];
    
    //执行第二种方式
//    [command.executionSignals subscribeNext:^(id  _Nullable x) {
//
//        NSLog(@"2222-%@", x);
//        [x subscribeNext:^(id  _Nullable x) {
//            NSLog(@"3333-%@", x);
//        }];
//    }];
    
    //执行第三种方式
    [command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
        NSLog(@"4444-%@", x);
    }];
    
    //监听信号的执行情况, skip跳过第一次,第一次不准确
    [[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
        BOOL isExecuting = [x boolValue];
        if (isExecuting) {
            NSLog(@"正在执行");
        } else {
            NSLog(@"执行完成");
        }
    }];
    
    [command execute:@1];

场景:监听按钮点击,网络请求

    //第一种创建方式
//    self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
//        NSLog(@"111--%@", input);
//
//        return [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
//
//            [subscriber sendNext:input];
//            [subscriber sendCompleted];
//            return nil;
//        }];
//    }];
    
    
    //第二种创建方式
    RACSubject *subject = [RACSubject subject];
    
    self.button.rac_command = [[RACCommand alloc] initWithEnabled:subject signalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        return [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
            
            [subscriber sendNext:input];
            [subscriber sendCompleted];
            return nil;
        }];
    }];
    
    [[self.button.rac_command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
        //控制按钮是否可以点击
        [subject sendNext:@(![x boolValue])];
    }];
    
    //监听按钮点击
    [self.button.rac_command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
        NSLog(@"222--%@", x);
    }];

rac_signalForSelector 监听一个方法是否被调用

KVO rac_valuesForKeyPath或RACObserve

@property (nonatomic) int age;
//第一种方式
[[self rac_valuesForKeyPath:@keypath(self, age) observer:self] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
}];
    
//第二种方式,宏
[RACObserve(self, age) subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
}];
    
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    self.age++;
}

rac_signalForControlEvents 监听按钮事件

[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@", x);
    }];

rac_addObserverForName 通知

//监听通知
//不需要管理观察者,RAC内部已经管理
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"Noti" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
    NSLog(@"%@", x);
}];
    
//发出通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"Noti" object:nil];

rac_textSignal textfiled文字改变

@weakify(self);
[self.field.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
    NSLog(@"%@", x);
    @strongify(self);
    self.button.enabled = x.length;
}];

RAC绑定

RAC(self.label, text) = self.field.rac_textSignal;

rac_liftSelector 序列,可以代替GCD

RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
    [subscriber sendNext:@"第一个数据"];
    
    return nil;
}];
    
RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
    [subscriber sendNext:@"第二个数据"];
    
    return nil;
}];
    
//Selector:当数组中所有信息都发送next的时候调用
//rac_liftSelector必要条件:有几个信号,方法就必须有几个参数,参数就是信号发出的值
[self rac_liftSelector:@selector(reloadDataFirst:second:) withSignals:signal1, signal2, nil];

- (void)reloadDataFirst:(NSString *)first second:(NSString *)second {
    NSLog(@"%@, %@", first, second);
}

bind 绑定,可以拦截数据进行处理之后再返回

[[self.field.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
    
    return ^ RACSignal * (id value, BOOL *stop) {
        
        NSString *result = [NSString stringWithFormat:@"%@%@", value, @"xb"];
        
        return [RACReturnSignal return:result];
    };
    
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"获取处理完的数据 %@", x);
}];

flattenMap 返回的是一个信号

[[self.field.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
    NSString *result = [NSString stringWithFormat:@"%@%@", value, @"xb"];
    return [RACReturnSignal return:result];
    
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"获取处理完的数据 %@", x);
}];

map 返回的是一个值

[[self.field.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
    NSString *result = [NSString stringWithFormat:@"%@%@", value, @"xb"];
    return result;
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"获取处理完的数据 %@", x);
}];

concat 拼接

//RACSubject 按顺序发送 
//RACReplaySubject  可以不按顺序发送
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACReplaySubject subject];
    
NSMutableArray *array = [NSMutableArray array];
    
//按顺序拼接,必须第一个信号发送完成,第二个信号才能获取值
[[signalA concat:signalB] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
    [array addObject:x];
}];
 
[signalB sendNext:@"B"];
[signalA sendNext:@"A"];
[signalA sendCompleted];
    
NSLog(@"%@", array);

/*
A
B
(A,B)
*/

then:拼接, 忽略掉上一个信号的值

RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        NSLog(@"执行信号A");
        
        [subscriber sendNext:@1];
        [subscriber sendCompleted];
        
        return nil;
    }];
    
//then:拼接, 忽略掉上一个信号的值
//可以解决block嵌套的问题
[[signalA then:^RACSignal * _Nonnull{
    
    return [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        NSLog(@"执行信号B");
        
        [subscriber sendNext:@2];
        [subscriber sendCompleted];
        
        return nil;
    }];
    
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
}];

/*
执行信号A
执行信号B
2
*/

merge 合并

RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];

//merge, 合并,只要任何一个信号发送,就能订阅,无序的整合信号数据
[[signalA merge:signalB] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
   
}];
    
[signalB sendNext:@"B"];
[signalA sendNext:@"A"];

/*
B
A
*/

zipWith 压缩信号成元组

RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
    
//zipWith, 压缩,同时发送数据,压缩信号数据变成元组
[[signalA zipWith:signalB] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
    RACTupleUnpack(NSString *a, NSString *b) = x;
    NSLog(@"%@ %@", a, b);
    
}];
    
[signalA sendNext:@"A"];
[signalB sendNext:@"B"];

combineLatestWith 合并, 任何一个信号,只要改变就能订阅到

//最多合并两个
[[self.field.rac_textSignal combineLatestWith:self.pwdField.rac_textSignal] subscribeNext:^(RACTwoTuple * _Nullable x) {
    RACTupleUnpack(NSString *name, NSString *password) = x;
   
    self.button.enabled = (name.length > 0 && password.length);
  
    NSLog(@"%@", x);
}];

combineLatest 合并多个, reduce 聚合

//reduce 聚合,把多个信号的值,聚合为一个值
//reduce参数:几个信号就几个参数,每个参数就是信号发出的值
[[RACSignal combineLatest:@[self.field.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id _Nullable (NSString *name, NSString *password){
    
    NSLog(@"%@ %@", name, password);
    
    return @(name.length > 0 && password.length > 0);
    
}] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
    self.button.enabled = [x boolValue];
}];


//RAC的写法, 响应式编程(绑定)
RAC(self.button, enabled) = [RACSignal combineLatest:@[self.field.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id _Nullable (NSString *name, NSString *password){
    
    NSLog(@"%@ %@", name, password);
    
    return @(name.length > 0 && password.length > 0);
    
}];

filter 过滤

[[self.field.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
    
    return value.length >= 6;
}] subscribeNext:^(NSString * _Nullable x) {
    NSLog(@"%@", x);
}];
    

interval定时器

//RACScheduler:多线程,管理线程
[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
    NSLog(@"%@", x);
}];

delay 延迟发送数据

[[[RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
    [subscriber sendNext:@"a"];
    [subscriber sendCompleted];
    return nil;
}] delay:2] subscribeNext:^(id  _Nullable x) {
    NSLog(@"%@", x);
}];

你可能感兴趣的:(RAC)