✎ReactiveCocoa使用OC(一)

导入项目

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

✎ReactiveCocoa使用OC(一)_第1张图片
1手机号不合法,不能点击登录
✎ReactiveCocoa使用OC(一)_第2张图片
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键进入代码:


✎ReactiveCocoa使用OC(一)_第3张图片
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)]

解释:


✎ReactiveCocoa使用OC(一)_第4张图片
RAC()方法解释

你可能感兴趣的:(✎ReactiveCocoa使用OC(一))