美文网首页
直接放代码了 Reactivecocoa 个人总结

直接放代码了 Reactivecocoa 个人总结

作者: 高乔人 | 来源:发表于2019-03-26 14:56 被阅读0次

pragma mark ----方法1

- (void)testOne{
    //总之:先订阅 再发送  订阅后才会触发^RACDisposable *(id<RACSubscriber> subscriber){}这个block
    
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //发送信号
        [subscriber sendNext:@"发送信号"];
        //不在发送信号,最好发送完成
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
//            NSLog(@"信号被销毁了");
        }];
    }];
    //订阅信号
    [signal subscribeNext:^(id x) {
    //这里接受拿到发送的信号
        NSLog(@"%@",x);  //发送信号
    }];
    [signal subscribeError:^(NSError *error) {
        //错误信息
    }];
    
}
#pragma mark ----方法2
- (void)testTwo{
    
    RACSubject *subject = [RACSubject subject];
    [subject subscribeNext:^(id x) {
        NSLog(@"第一个订阅者%@",x);
    }];
    [subject subscribeNext:^(id x) {
        NSLog(@"第2个订阅者%@",x);
    }];
    [subject sendNext:@"4555"];
    [subject sendCompleted];
    
}
#pragma mark ---方法3 元组(数组使用)
- (void)test3{
    RACTuple *tuple=[RACTuple tupleWithObjectsFromArray:@[@"123",@"345",@1]];
    NSString *first=tuple[0];
    NSLog(@"%@",first);
    //数组
    NSArray *arr=@[@"213",@"321",@1];
    [arr.rac_sequence.signal subscribeNext:^(id x) {
        NSLog(@"高级写法遍历数组%@",x);
    }];
    //字典
    NSDictionary *dict=@{@"sex":@"女",@"name":@"打交道的",@"age":@18};
    //转换成集合
    [dict.rac_sequence.signal subscribeNext:^(id x) {
        RACTupleUnpack(NSString *key,NSString *value)=x;
        NSLog(@"%@ %@",key,value);
    }];
    
}

#pragma mark ---//RACMulticastConnection用于相当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。
- (void)test4{
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"1"];//发送消息,订阅者接受消息
        return [RACDisposable disposableWithBlock:^{
            
        }];
    }];
    //订阅信息-运行结果,会执行两遍发送请求,也就是每次订阅都会发送一次请求
    [signal subscribeNext:^(id x) {
        NSLog(@"接受消息");
    }];
    [signal subscribeNext:^(id x) {
        NSLog(@"接受消息");
    }];
    //解决重复问题
    RACSignal *connectionSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"接受请求");
        return [RACDisposable disposableWithBlock:^{
        }];
    }];
    
    //创建连接
    RACMulticastConnection *connection = [connectionSignal publish];
    [connection.signal subscribeNext:^(id x) {
        NSLog(@"第一个信号");
    }];
    [connection.signal subscribeNext:^(id x) {
        NSLog(@"第二个信号");
    }];
    [connection connect];
}
#pragma mark ----RACCommand:RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程-使用场景:监听按钮点击,网络请求
- (void)test5{
    //创建命令
    RACCommand *command=[[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        NSLog(@"执行命令");
        //创建信号,用来传递数据
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"请求数据"];
            //注意:数据传递完,最好用sendCompleted,这时命令才执行完
            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"数据销毁");
            }];
        }];
    }];
    //强引用命令,,不要被销毁,否则接收不到消息
    command=command;
    [command.executing subscribeNext:^(id x) {
        if ([x boolValue]==YES) {
            NSLog(@"当前正在执行");
        }else{
            NSLog(@"执行完成/没有执行");
        }
    }];
    //执行命令
    [command execute:@1];
    
}

#pragma mark ----代替代理方法
- (void)btnClick{
    NSLog(@"ahgagagh");
}

到这里是高级用法

import "myTestViewController.h"

    #import <ReactiveCocoa/ReactiveCocoa.h>
    #import "FlagItem.h"

    @interface myTestViewController ()
    @property (nonatomic,strong) NSMutableArray *dataArray;
    @property (nonatomic,strong) RACCommand *command;
    @end

    @implementation myTestViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
       
        self.view.backgroundColor = [UIColor cyanColor];
        [self testPlist];
    }

    - (void)testPlist{
        
        NSBundle * bundle = [NSBundle mainBundle];
        NSString * path = [bundle pathForResource:@"test.plist" ofType:nil];
        NSLog(@"%@",path);
        NSArray *arr = [NSArray arrayWithContentsOfFile:path];
        
            for (NSDictionary *str in arr) {
                NSLog(@"======%@",str);
            }

        
        
        
    }
    - (void)ReactiveCocoaUseDetail{
    //    ReactiveCocoa开发中常见用法。
    //    1 代替代理:
        //比如我现在写一个redview  控制redview中的按钮的点击事件
    //    rac_signalForSelector:用于替代代理。
        
    //    2 代替KVO :
    //    rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变。
    //    3 监听事件:

    //    rac_signalForControlEvents:用于监听某个事件。
    //    4 代替通知:

    //    rac_addObserverForName:用于监听某个通知。
    //    5 监听文本框文字改变:

    //    rac_textSignal:只要文本框发出改变就会发出这个信号。
    //    6 处理当界面有多次请求时,需要都获取到数据时,才能展示界面

    //    rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法。
    //    使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
        
    }
    //RACCommand RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,可以很方便的监控事件的执行过程。
    - (void)mycocoaTestRACCommand{
        
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
          
            NSLog(@"执行命令");
            
            // 创建空信号,用来传递数据
            return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                
                [subscriber sendNext:@"请求数据"];
                
                // 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
                [subscriber sendCompleted];
                
                return nil;
            }];

        }];
        
        // 强引用命令,不要被销毁,否则接收不到数据
        _command = command;
        // 3.订阅RACCommand中的信号
        [command.executionSignals subscribeNext:^(id x) {
            
            [x subscribeNext:^(id x) {
                
                NSLog(@"%@",x);
            }];
            
        }];


    }

    //RACSequence和RACTuple简单使用
    - (void)mycocoaTestRACSequence{
        // 1.遍历数组
        NSArray *numbers = @[@1,@2,@3,@4];
        // 这里其实是三步
        // 第一步: 把数组转换成集合RACSequence    numbers.rac_sequence
        // 第二步: 把集合RACSequence转换RACSignal信号类,  numbers.rac_sequence.signal
        // 第三步: 订阅信号,激活信号,会自动把集合中的所有值,遍历出来。
        [numbers.rac_sequence.signal subscribeNext:^(id x) {
            
            NSLog(@"%@",x);//这里的值  是遍历得到的结果
        }];

        // 2.遍历字典,遍历出来的键值对会包装成RACTuple(元组对象)
        NSDictionary *dict = @{@"name":@"xmg",@"age":@18};
        [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {
            
            // 解包元组,会把元组的值,按顺序给参数里面的变量赋值
            RACTupleUnpack(NSString *key,NSString *value) = x;
            
            // 相当于以下写法
            //        NSString *key = x[0];
            //        NSString *value = x[1];
            
            NSLog(@"%@ %@",key,value);
            
        }];
        //3. 最终我是要将字典转为模型的   这里就写一个RAC字典转模型的写法
        
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];
        
        NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
        
        NSMutableArray *flags = [NSMutableArray array];
        
        _dataArray = flags;
        
        // rac_sequence注意点:调用subscribeNext,并不会马上执行nextBlock,而是会等一会。
        [dictArr.rac_sequence.signal subscribeNext:^(id x) {
            // 运用RAC遍历字典,x:字典
            
            FlagItem *item = [FlagItem flagWithDict:x];
            
            [self.dataArray addObject:item];
            
        }];

        //还有一个高级的写法 如下:
        //map 是映射的意思   目的:把原始值value映射成一个新值 也就是给模型赋值
        NSArray *flags2 = [[dictArr.rac_sequence map:^id(id value) {
            
            return [FlagItem flagWithDict:value];
            
        }] array];
        
    }
    - (void)mycocoaTestRACSubject{
        
        //创建信号
        RACSubject *subject = [[RACSubject alloc] init];
        //订阅信号
        [subject subscribeNext:^(id x) {
            
            //这里只有发送完信号,才会来
            NSLog(@"第一个订阅者");
        }];
        [subject subscribeNext:^(id x) {
             //这里只有发送完信号,才会来
            NSLog(@"第二个订阅者");
        }];
        
        //发送信号
        //会遍历信号的订阅着  完事儿之后才会 触发订阅者的block
        [subject sendNext:[NSMutableArray arrayWithObjects:@1,@2,@3,nil]];
        
        
        /*
         RACSubject  也可以用作代理  例如:
         
         //这是第一个控制器
         @implementation OneViewController
         - (IBAction)btnClick:(id)sender {
         
         // 创建第二个控制器
         TwoViewController *twoVc = [[TwoViewController alloc] init];
         
         // 设置代理信号
         twoVc.delegateSignal = [RACSubject subject];
         
         // 订阅代理信号
         [twoVc.delegateSignal subscribeNext:^(id x) {
         
         NSLog(@"点击了通知按钮");  这里可以通过这个 id 把需要的数据传过去
         }];
         
         // 跳转到第二个控制器
         [self presentViewController:twoVc animated:YES completion:nil];
         
         }
         
    **********************************************************************
         //第二个控制中
         步骤二:监听第二个控制器按钮点击
         @implementation TwoViewController
         - (IBAction)notice:(id)sender {
         // 通知第一个控制器,告诉它,按钮被点了
         
         // 通知代理
         // 判断代理信号是否有值
         if (self.delegateSignal) {
         // 有值,才需要通知
         [self.delegateSignal sendNext:nil];    这里拿到第一个控制器传过来的数据
         }
    }

         
         
         **/
        
        
    }

    - (void)mycocoaTestRACSignal{
        
        //1 创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            //2 发送信号    这里我猜测应该是使用的KVO添加的监听着 底层应该就是用的这个方法 addObserver:<#(nonnull NSObject *)#> forKeyPath:<#(nonnull NSString *)#> options:<#(NSKeyValueObservingOptions)#> context:<#(nullable void *)#>
           
            [subscriber sendNext:@123];
            return [RACDisposable disposableWithBlock:^{
                //信号取消或者 信号错误发生错误  回来到这里block
            }];
        }];
        
        //3 激活信号
        [signal subscribeNext:^(id x) {
            
            //每当有信号发出数据,就会调用block.  这里我猜测应该是 KVO用来监听信号的变化,也就是说,如果信号没有发生改变,这里是不会走的, block不会执行
            NSLog(@"%s",__func__);
            
        }];
        
        
    }
    - (void)btnClick:(UIButton *)sender{
        
        
        
    }
    @end

相关文章

网友评论

      本文标题:直接放代码了 Reactivecocoa 个人总结

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