ReactiveCocoa

基本用法
RACSubject

     /* 创建信号 */
    RACSubject *subject = [RACSubject subject];
    /* 订阅信号(通常在别的视图控制器中订阅,与代理的用法类似) */
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"信号内容2:%@", x);
    }];
    /* 发送信号 */
    [subject sendNext:@"发送信号2"];

RACSignal

 // 1.创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        // 3.发送信号
        [subscriber sendNext:@"ws"];
        // 4.取消信号,如果信号想要被取消,就必须返回一个RACDisposable
        // 信号什么时候被取消:1.自动取消,当一个信号的订阅者被销毁的时候机会自动取消订阅,2.手动取消,
        //block什么时候调用:一旦一个信号被取消订阅就会调用
        //block作用:当信号被取消时用于清空一些资源
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"取消订阅");
        }];
    }];
    // 2. 订阅信号
    //subscribeNext
    // 把nextBlock保存到订阅者里面
    // 只要订阅信号就会返回一个取消订阅信号的类
    RACDisposable *disposable = [signal subscribeNext:^(id x) {
        // block的调用时刻:只要信号内部发出数据就会调用这个block
        NSLog(@"======%@", x);
    }];
    // 取消订阅
    [disposable dispose];

RAC 的元祖,

跟我们 OC 的数组其实是一样的,它其实就是封装了我们 OC 的数组
    /* 创建元祖 */
    RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
    
    /* 从别的数组中获取内容 */
    RACTuple *TempTuple = [RACTuple tupleWithObjectsFromArray:@[@"a",@"b",@"c"]];
    
    /* 利用 RAC 宏快速封装 */
    RACTuple *newTuple = RACTuplePack(@"10", @"20", @"30", @"40", @"50");
    
    NSLog(@"取元祖内容:%@---%@", tuple,tuple[0]);
    NSLog(@"第一个元素:%@---%@", TempTuple,[TempTuple first]);
    NSLog(@"最后一个元素:%@---%@", newTuple,[newTuple last]);
    
#pragma 4 遍历array和dictionary可以省去使用 for 循环来遍历
    /* 遍历数组 */
    NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
    [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"数组内容:%@", x); // x 可以是任何对象
    }];
    
    /* 遍历字典 */
    NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
    [dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) {
        
        RACTupleUnpack(NSString *key, NSString *value) = x; // x 是一个元祖,这个宏能够将 key 和 value 拆开
        NSLog(@"字典内容:%@:%@", key, value);
    }];
   
    // 替换数据
    /* 内容操作 */
    NSArray *array1 = @[@"1", @"2", @"3", @"4", @"5"];
    NSArray *newArray1 = [[array1.rac_sequence map:^id _Nullable(id  _Nullable value) {
        
        NSLog(@"数组内容:%@", value);
        
        return @"0"; // 将所有内容替换为 0
        
    }] array];
    
    /* 内容快速替换 */
    NSArray *array2 = @[@"1", @"2", @"3", @"4", @"5"];
    NSArray *newArray2 = [[array2.rac_sequence mapReplace:@"0"] array]; // 将所有内容替换为 0
    
    NSLog(@"*****%@\n****%@",newArray1,newArray2);
文本框
textField.rac_textSignal
按钮
[getButton rac_signalForControlEvents:UIControlEventTouchUpInside] 
试图
[self.topView rac_signalForSelector:@selector(loginAction)]

可代替代理
 rac_signalForControlEvents: 和 rac_signalForSelector
 
   [[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
     NSLog(@" view 中的按钮被点击了");
   }];

    RAC:把一个对象的某个属性绑定一个信号,只要发出信号,就会把信号的内容给对象的属性赋值
    // 给label的text属性绑定了文本框改变的信号
    RAC(self.label, text) = self.textField.rac_textSignal;
    
   RACObserveL:快速的监听某个对象的某个属性改变
    [RACObserve(commodityVC.model, dataNum) subscribeNext:^(id  _Nullable x) {
        kStrongSelf(self)
        self.clearBT.hidden = [x integerValue]==0?YES:NO;
        self.eidtBT.hidden = [x integerValue]==0?YES:NO;
    }];

   RACTuple *tuple = RACTuplePack(@1,@2,@4);
    // 宏的参数类型要和元祖中元素类型一致, 右边为要解析的元祖。
    RACTupleUnpack_(NSNumber *num1, NSNumber *num2, NSNumber * num3) = tuple;// 4.元祖
    // 快速包装一个元组
    // 把包装的类型放在宏的参数里面,就会自动包装
    NSLog(@"%@ %@ %@", num1, num2, num3);

可代替代理

 rac_signalForControlEvents: 和 rac_signalForSelector
   [[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
     NSLog(@" view 中的按钮被点击了");
   }];

代替 KVO 监听

     [[view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id  _Nullable x) {
         NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果
    }];
   简单用宏
   [RACObserve(commodityVC.model, dataNum) 

Notification 可省去在 -(void)dealloc {} 中清除通知和监听通知创建方法的步骤

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@ 键盘弹起", x); // x 是通知对象
    }];

代替 NSTimer 计时

    disposable = [[RACSignal interval:3.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        NSLog(@"当前时间:%@", x); // x 是当前的系统时
    }];

信号过滤

// 一般和文本框一起用,添加过滤条件
- (void)fliter {
    // 只有当文本框的内容长度大于5,才获取文本框里的内容
    [[self.textField.rac_textSignal filter:^BOOL(id value) {
        // value 源信号的内容
        return [value length] > 5;
        // 返回值 就是过滤条件。只有满足这个条件才能获取到内容
    }] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
} 

//distinctUntilChanged:-- 如果当前的值跟上一次的值一样,就不会被订阅到
- (void)distinctUntilChanged {
    RACSubject *subject = [RACSubject subject];
    [[subject distinctUntilChanged] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // 发送信号
    [subject sendNext:@1];
    [subject sendNext:@2];
    [subject sendNext:@2]; // 不会被订阅
}

// ignore: 忽略掉一些值
- (void)ignore {
    //ignore:忽略一些值
    //ignoreValues:表示忽略所有的值
    // 1.创建信号
    RACSubject *subject = [RACSubject subject];
    // 2.忽略一些值
    RACSignal *ignoreSignal = [subject ignore:@2]; // ignoreValues:表示忽略所有的值
    // 3.订阅信号
    [ignoreSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // 4.发送数据
    [subject sendNext:@1];
    [subject sendNext:@3];
    [subject sendNext:@2];

}

// 跳跃 : 如下,skip传入2 跳过前面两个值
// 实际用处: 在实际开发中比如 后台返回的数据前面几个没用,我们想跳跃过去,便可以用skip
- (void)skip {
    RACSubject *subject = [RACSubject subject];
    [[subject skip:1] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    [subject sendNext:@1];
    [subject sendNext:@2];
    [subject sendNext:@3];
}

// take:可以屏蔽一些值,去前面几个值---这里take为2 则只拿到前两个值
- (void)take {
    RACSubject *subject = [RACSubject subject];
    [[subject take:1] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // 发送信号
    [subject sendNext:@1];
    [subject sendNext:@2];
    [subject sendNext:@3];
}

//takeLast:和take的用法一样,不过他取的是最后的几个值,如下,则取的是最后两个值
//注意点:takeLast 一定要调用sendCompleted,告诉他发送完成了,这样才能取到最后的几个值
- (void)takeLast {
    RACSubject *subject = [RACSubject subject];
    [[subject takeLast:1] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // 发送信号
    [subject sendNext:@1];
    [subject sendNext:@2];
    [subject sendNext:@3];
    [subject sendCompleted];
}

// takeUntil:---给takeUntil传的是哪个信号,那么当这个信号发送信号或sendCompleted,就不能再接受源信号的内容了。
- (void)takeUntil {
    RACSubject *subject = [RACSubject subject];
    RACSubject *subject2 = [RACSubject subject];
    [[subject takeUntil:subject2] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    [subject2 subscribeNext:^(id  _Nullable x) {
        NSLog(@"?%@",x);
    }];
    // 发送信号
    [subject sendNext:@1];
    [subject sendNext:@2];
    [subject2 sendNext:@3];  // 1
//    [subject2 sendCompleted]; // 或2
    [subject sendNext:@4];
    [subject2 sendNext:@5];
    [subject2 sendNext:@6];
    [subject2 sendNext:@8];
}

映射

- (void)map {
    // 创建信号
    RACSubject *subject = [RACSubject subject];
    // 绑定信号
    RACSignal *bindSignal = [subject map:^id(id value) {
        
        // 返回的类型就是你需要映射的值
        return [NSString stringWithFormat:@"?ws:%@", value]; //这里将源信号发送的“123” 前面拼接了ws:
    }];
    // 订阅绑定信号
    [bindSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    // 发送信号
    [subject sendNext:@"123"];

}


UIButton *getButton = [UIButton buttonWithType:UIButtonTypeSystem];
getButton.frame = CGRectMake(50, 550, 100, 50);
getButton.backgroundColor = [UIColor whiteColor];

[getButton setTitle:@"get" forState:UIControlStateNormal];
[[getButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
    RACSignal *signal = [[RMBaseSessionManager sharedInstance] HTTPRequeatHttpMed:HTTPMethodTypeGET URLStr:@"https://api.douban.com/v2/book/search" Params:@{@"q":textField.text}];
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"--------%@",x);
        [getButton setTitle:@"请求成功" forState:UIControlStateNormal];
    }];
    [signal subscribeError:^(NSError * _Nullable error) {
        NSLog(@"--------%@",error);
    }];
}];
[self.view addSubview:getButton];

#pragma 7 属性/状态的实时监听
RAC(getButton, enabled) = [RACSignal combineLatest:@[textField.rac_textSignal, textField2.rac_textSignal] reduce:^id _Nullable(NSString * username, NSString * password){
return @(username.length && password.length);
}];

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值