美文网首页
✎ReactiveCocoa使用OC(一)

✎ReactiveCocoa使用OC(一)

作者: 树懒啊树懒 | 来源:发表于2017-09-14 17:17 被阅读234次

    导入项目

    (1)OC项目导入RAC: pod 'ReactiveCocoa', '~> 2.5'
    (2)编译设置
    xcode设置 "build setting --> Apple LLVM8.1 - Language - Objective-c --> Weak References in Manual Retain Release" 设置为 Yes 或者 删除掉 __weak qualifiers

    不然会报错:
    Cannot create __weak reference in file using manual reference counting

    一 :先简单使用

    场景(1):登录页面 ,监听手机号和验证码是否合法,来随时调整确定按钮的背景色或者是否能够点击

    1手机号不合法,不能点击登录 2手机号合法,可以点击登录

    代码:

    初始化self.phone 和 self.codeT 以后调用下面方法

    - (void)RACSignalInit {
    //创建self.phone输入信息的监听
        RACSignal* nameSignal = [self.phone.rac_textSignal map:^id(NSString* value) {
            if ([self checkPhoneNum]) {//判断手机号是否合法
                return @(YES);
            } else{
                return @(NO);
            }
        }];
       //创建self.codeT输入信息的监听 
        RACSignal* passwordSignal = [self.codeT.rac_textSignal map:^id(NSString* value) {
            if ([self checkCode]) {//判断验证码是否合法
                return @(YES);
            } else{
                return @(NO);
            }
        }];
        
    //合并两者改变监听,改变按钮背景色
        RAC(self.loginBtn,backgroundColor) = [RACSignal combineLatest:@[nameSignal,passwordSignal] reduce:^id(NSNumber* phone,NSNumber*code){
           //两者都满足
            BOOL isOK = phone.boolValue&&code.boolValue;
            return isOK ? color_green_al : color_gray_F2;
        }];
        
    }
    

    //上面方法也可以这样写(直接把block丢进去):

    RACSignal * fallInSignal = [RACSignal combineLatest:@[ self.userNameFiled.rac_textSignal, self.userPwdFiled.rac_textSignal ] reduce:^(NSString * userName,NSString * pwd) { 
           //比如校验输入信息长度大于0
            return @(userName.length > 0 && pwd.length > 0); 
    }]; 
    //两者改变监听,改变按钮enabled
    RAC(self.submitButton,enabled) = fallInSignal;
    

    RAC好神奇?看看下面原始方法实现该功能:

    //设置代理:(相当于[self.phone.rac_textSignal map:])
    .....
    self.phone.delegate = self;
            [self.phone addTarget:self action:@selector(textFieldEditing:) forControlEvents:UIControlEventEditingChanged];
    
    .....
    self.CodeT.delegate = self;
            [self.CodeT addTarget:self action:@selector(textFieldEditing:) forControlEvents:UIControlEventEditingChanged];
    
    //调用方法(相当于 [RACSignal combineLatest:])
    - (void)textFieldEditing:(UITextField *)sender {
        //校验手机号和验证码是否合法
        if (![self checkPhoneNum] || ![self checkCode])  {
            [self.loginBtn setBackgroundColor:color_gray_F2];
        } else {
            [self.loginBtn setBackgroundColor:color_green_al];
        }
    }
    //(想想把这些功能通过block封装一下,结合宏使用效果会怎样呢?)
    

    经过以上解释,明白功能流程,可是RAC不是这么简单的.

    二 方法名称解释

    (1).rac_textSignal

    这里我们按住command键进入代码:


    rac_textSignal

    发现UITextField的.rac_textSignal返回一个对象RACSignal,然后如上截图箭头所示,里面包含几种方法,其中就有刚才使用过的map.

    解释:通过方法名称基本可以判断rac_textSignal( 前缀rac + 类型text + 返回模型Signal):意思是返回一个text操作相关的RACSignal(继承NSObject)模型.而这个model可以操作几种方法(截图箭头).

    (2)map:

    显然map应该是上面UITextField扩展类 rac_textSignal中的block,返回的是text值:

    map:^(UITextField *x) {
                return x.text;
            }]
    
    (3)宏RAC( xx , xx )

    先按住command键进入代码:RACSubscriptingAssignmentTrampoline.h

    使用方法:

    /// Examples
    ///  RAC(self, objectProperty) = objectSignal;
    ///  RAC(self, stringProperty, @"foobar") = stringSignal;
    ///  RAC(self, integerProperty, @42) = integerSignal;
    

    用户调用宏定义(metamacro_argcount:属性数判断):

    #define RAC(TARGET, ...) \
        metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
            (RAC_(TARGET, __VA_ARGS__, nil)) \
            (RAC_(TARGET, __VA_ARGS__))
    

    被使用的内部宏定义2,用户不要调用(observeValueForKeyPath):

    /// Do not use this directly. Use the RAC macro above.
    #define RAC_(TARGET, KEYPATH, NILVALUE) \
        [[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:(TARGET) nilValue:(NILVALUE)][@keypath(TARGET, KEYPATH)]
    

    解释:


    RAC()方法解释

    相关文章

      网友评论

          本文标题:✎ReactiveCocoa使用OC(一)

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