导入项目
(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):登录页面 ,监听手机号和验证码是否合法,来随时调整确定按钮的背景色或者是否能够点击
代码:
初始化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键进入代码:
发现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)]
解释: