RAC学习

作者: marlonxlj | 来源:发表于2019-05-14 18:06 被阅读0次

    更新时间:2019-6-10

    更新内容:Injection 热加载 RAC中 崩溃问题的解决办法

    直接使用会崩溃
    #pragma mark -- OC 中如果项目中包含RAC,使用injected方法会导致程序崩溃,解决的办法是使用通知的方式@"INJECTION_BUNDLE_NOTIFICATION"
    //- (void)injected
    //{
    //    NSLog(@"I've been injected: %@", self);
    //}
    
    
    解决方法如下:
    KK_WeakSelf
        [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"INJECTION_BUNDLE_NOTIFICATION" object:nil] takeUntil:[self rac_willDeallocSignal]] subscribeNext:^(NSNotification * _Nullable x) {
            KK_StrongSelf
            [self hotReloadView];
        }];
    
    

    更新时间:2019-05-14

    RAC_Demo下载地址

    目录:

    1. TextField的使用

    2. Slider控制bgView的背景颜色

    3. Network网络的处理

    4. NSNotice通知事件

    5. Tap事件的添加

    6. TableViewCell中2个View添加事件

    【效果图如下】

    iToolsScreenecord019-05-159.53.58.gif

    1. TextField的使用

    TextField的使用情况,用户输入用户名,密码大于6位,改变登录按钮的背景色和是否可以点击的事件。

    - (void)settingStatus{
        
        //按钮的使能
        RAC(self.loginBtn,backgroundColor) = [RACSignal combineLatest:@[self.userNameTextField.rac_textSignal,self.userPwdTextField.rac_textSignal] reduce:^id (NSString* name,NSString *pwd){
            BOOL enable = [name length] > 0 && [pwd length] > 6;
            self.loginBtn.enabled = enable;
            return enable ? [UIColor redColor] : [UIColor lightGrayColor];
        }];
        
        [[self.loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
            
            NSLog(@"n:%@,p:%@",self.userNameTextField.text,self.userPwdTextField.text);
        }];
    }
    
    

    2. Slider控制bgView的背景颜色

    - (void)settingSubView{
        //绑定3个信号
        RACSignal *redSignal = [self bindSlider:self.redSlider textField:self.redTextField];
        RACSignal *blueSignal = [self bindSlider:self.blueSlider textField:self.blueTextField];
        RACSignal *yellowSignal = [self bindSlider:self.yellowSlider textField:self.yellowTextField];
        
        RACSignal *changeSignal = [[RACSignal combineLatest:@[redSignal,blueSignal,yellowSignal]] map:^id _Nullable(RACTuple * value) {
            return [UIColor colorWithRed:[value[0] floatValue] green:[value[1] floatValue] blue:[value[2] floatValue] alpha:1];
        }];
        //这个宏传入的参数: 一个是需要修改的对象,一个是这个对象的熟悉,最后是给她进行赋值。
        RAC(self.showBgView,backgroundColor) = changeSignal;
    }
    
    - (RACSignal *)bindSlider:(UISlider *)slider textField:(UITextField *)textField{
        
        RACSignal *textSignal = [[textField rac_textSignal] take:1];
        
        //终端
        RACChannelTerminal *signalSlider = [slider rac_newValueChannelWithNilValue:nil];
        RACChannelTerminal *signalText = [textField rac_newTextChannel];
        
        //文本终端订阅slider终端
        [signalText subscribe:signalSlider];
        //slider订阅text终端
        [[signalSlider map:^id _Nullable(id  _Nullable value) {
            return [NSString stringWithFormat:@"%.02f",[value floatValue]];
        }] subscribe:signalText];
        
        return [[signalText merge:signalSlider] merge:textSignal];
    }
    
    

    3. Network网络的处理

    
    
    - (void)startRequest{
        //1、单个请求
        [[self.signalBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
            [self requestSignal];
        }];
        
        //2、异步请求
        [[self.asyncBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
            [self requestAsyncFunc];
        }];
        
        //3、同步请求,都执行完后才操作
        [[self.sysBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
            [self requestSyncFunc];
        }];
        
        //4、其他请求
        __weak typeof(self) weakSelf = self;
        [[self.otherBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
            [weakSelf showTextInfo:@"暂无内容"];
        }];
    }
    
    - (void)requestSignal{
        __weak typeof(self) weakSelf = self;
        [[self signalFromJson:urlPath cityName:@"成都"] subscribeNext:^(id  _Nullable x) {
            NSString *tmpStr = [NSString stringWithFormat:@"%@",x[@"result"]];
            [weakSelf showTextInfo:tmpStr];
        }];
    }
    
    - (void)requestAsyncFunc{
        __weak typeof(self) weakSelf = self;
        RACSignal *reqSignal = [self signalFromJson:urlPath cityName:@"上海"];
        RACSignal *reqSignal1 = [self signalFromJson:urlPath cityName:@"杭州"];
        RACSignal *reqSignal2 = [self signalFromJson:urlPath cityName:@"南京"];
        
        //2、同步执行,三个都执行完后才返回结果
        [[RACSignal combineLatest:@[reqSignal,reqSignal1,reqSignal2]] subscribeNext:^(RACTuple * _Nullable x) {
            NSArray *array = (NSArray *)x;
            NSString *tmpStr = [NSString stringWithFormat:@"返回的结果都在这个数组里面,没有顺序,执行完后才有结果:%ld个结果",array.count];
            [weakSelf showTextInfo:tmpStr];
        }];
        
    }
    
    - (void)requestSyncFunc{
        __weak typeof(self) weakSelf = self;
        RACSignal *reqSignal = [self signalFromJson:urlPath cityName:@"上海"];
        RACSignal *reqSignal1 = [self signalFromJson:urlPath cityName:@"杭州"];
        RACSignal *reqSignal2 = [self signalFromJson:urlPath cityName:@"南京"];
       
        //1、同步请求
        [[[reqSignal merge:reqSignal1] merge:reqSignal2] subscribeNext:^(id  _Nullable x) {
            NSString *tmpStr = [NSString stringWithFormat:@"会有三次的请求返回,每次的结果都是:\n %@",x[@"result"]];
            //这里会把三个请求的结果依次在这里返回回来
            [weakSelf showTextInfo:tmpStr];
        }];
    }
    
    - (void)otherRequestFunc{
        __weak typeof(self) weakSelf = self;
        //1、顺序执行,执行完第一个,再执行第二个,第二个完成再执行第三个
        RACSignal *reqSignal = [self signalFromJson:urlPath cityName:@"上海"];
        RACSignal *reqSignal1 = [self signalFromJson:urlPath cityName:@"杭州"];
        RACSignal *reqSignal2 = [self signalFromJson:urlPath cityName:@"南京"];
        [[[reqSignal then:^RACSignal * _Nonnull{
            NSLog(@"第一个信号请求完成");
            return reqSignal1;
        }] then:^RACSignal * _Nonnull{
            NSLog(@"第二个信号请求完成");
            return reqSignal2;
        }] subscribeNext:^(id  _Nullable x) {
            NSString *tmpStr = [NSString stringWithFormat:@"%@",x[@"result"]];
            //这里会把三个请求的结果依次在这里返回回来
            [weakSelf showTextInfo:tmpStr];
            NSLog(@"第三个信号请求完成");
        }];
    }
    
    - (RACSignal *)signalFromJson:(NSString *)urlStr cityName:(NSString *)cityName{
        
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
            
            NSString *urlTmp = [NSString stringWithFormat:@"%@?cityname=%@&dtype=%@&format=%@&key=%@",urlStr,cityName,@"json",@(1),@"bd1a721f3c8dae7c601c2b024afb367b"];
            //将网址转化为UTF8编码
            NSString *urlStringUTF8 = [urlTmp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStringUTF8]];
            request.HTTPMethod = @"GET";
            NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
            NSURLSessionTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                if (error) {
                    [subscriber sendError:error];
                }
                else{
                    NSError *e;
                    NSArray *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&e];
                    if (e) {
                        [subscriber sendError:e];
                    }
                    else{
                        [subscriber sendNext:jsonDict];
                        [subscriber sendCompleted];
                    }
                }
            }];
            
            [dataTask resume];
            
            return [RACDisposable disposableWithBlock:^{
                
            }];
        }];
    }
    
    - (void)showTextInfo:(NSString *)info{
        //注意:这里一定要在主线程里面更新赋值,不然会造成崩溃的问题.
        __weak typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.showTextView.text = info;
        });
    }
    
    

    4. NSNotice通知事件

    发送通知,由于我是直接从Controller的TableViewCell中push过去的,所以处理有点不一样。
    if ([vcStr isEqualToString:@"NSNotionController"]) {
            //无论在push操作前或后发送通知,当push到SecondViewController中时,是接收不到通知的。
            //通过NSLog(@"Thread:%@",[NSThread currentThread]);或[NSOperationQueue currentQueue]我们可以查到push时的线程和接收通知时的线程为主线程,输出:Thread:<NSThread: 0x170072d80>{number = 1, name = main}。
            //顺序还有影响,如果把通知放在push之前,在接收通知的时候是收不到的,放在主线程的后面才可以收到
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                [self.navigationController pushViewController:[NSClassFromString(vcStr) new] animated:YES];
            }];
            
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
               [[NSNotificationCenter defaultCenter] postNotificationName:@"NSNotionController" object:@"TestNotice"];
            }];
        }
    
    
    接收通知
    [[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"NSNotionController" object:nil] takeUntil:[self rac_willDeallocSignal]] subscribeNext:^(NSNotification * _Nullable x) {
          dispatch_async(dispatch_get_main_queue(), ^{
              weakSelf.noLable.text = x.object;
          });
      }];
    
    

    5. Tap事件的添加

    - (void)addTapForView{
        UITapGestureRecognizer *redTap = [[UITapGestureRecognizer alloc] init];
        [self.redView addGestureRecognizer:redTap];
        [[redTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            [self showLableInfo:x];
        }];
        
        UITapGestureRecognizer *yellowTap = [[UITapGestureRecognizer alloc] init];
        [self.yellowView addGestureRecognizer:yellowTap];
        [[yellowTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            [self showLableInfo:x];
        }];
    }
    
    - (void)showLableInfo:(UIGestureRecognizer *)taps{
        self.showLable.text = [NSString stringWithFormat:@"Tag:%ld",taps.view.tag];
    }
    
    

    6. TableViewCell中2个View添加事件

    Cell中的代码:
    - (void)addTapForImageView{
        UITapGestureRecognizer *redTap = [[UITapGestureRecognizer alloc] init];
        [self.leftImageView addGestureRecognizer:redTap];
        self.leftImageView.tag = 100;
        self.leftImageView.layer.masksToBounds = YES;
        self.leftImageView.layer.cornerRadius = 3;
        [[redTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            [self showLableInfo:x];
        }];
        
        UITapGestureRecognizer *yellowTap = [[UITapGestureRecognizer alloc] init];
        [self.rightImageView addGestureRecognizer:yellowTap];
        self.rightImageView.layer.masksToBounds = YES;
        self.rightImageView.layer.cornerRadius = 3;
        self.rightImageView.tag = 101;
        [[yellowTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
            [self showLableInfo:x];
        }];
        
        self.subject = [RACSubject subject];
    }
    - (void)showLableInfo:(UIGestureRecognizer *)taps{
        [self.subject sendNext:taps];
        //不能加这句话因为,如果已经完成了,就不能在接收发送的消息了
    //    [self.subject sendCompleted];
        
    }
    
    
    Controller中的代码:
    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        TapTableControllerCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
        
        UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 40)];
        
        UILabel *showLable = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, CGRectGetWidth(bgView.frame)-40,CGRectGetHeight(bgView.frame))];
        showLable.font = [UIFont systemFontOfSize:16];
        showLable.text = @"点击了:";
        [bgView addSubview:showLable];
        [[cell.subject takeUntil:cell.rac_prepareForReuseSignal] subscribeNext:^(UIGestureRecognizer * x) {
            NSString *tmp = [NSString stringWithFormat:@"点击了: Tag:%ld",x.view.tag];
            showLable.text = tmp;
        }];
        
        return bgView;
    }
    
    

    相关文章

      网友评论

          本文标题:RAC学习

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