ReactiveCocoa用法和宏
20 Mar 2016
常见用法
之前提到了RAC可以代替代理、KVO等。现在来看看具体用法。
代替代理:
-
rac_signalForSelector
:用于替代代理。 -
原理:判断一个方法有没有调用,如果调用了就会自动发送一个信号。
-
需求:自定义CustomView,监听自定义view中按钮点击
-
之前都是需要通过代理监听,给自定义view添加一个代理属性,点击按钮的时候,通知代理做事情。
-
rac_signalForSelector
:把调用某个对象的方法的信息转换成信号,就要调用这个方法,就会发送信号。 -
这里表示只要CustomView调用btnClick,就会发出信号,订阅就好了。
代码:
//CustomView
- (IBAction)buttonDidClick:(UIButton *)sender {
NSLog(@"buttonDidClick");
}
//DelegateViewController
[[self.customView rac_signalForSelector:@selector(buttonDidClick:)] subscribeNext:^(id x) {
NSLog(@"控制器知道:点击了按钮");
}];
2016-03-20 22:43:17.731 RACDemo[46034:5333662] buttonDidClick
2016-03-20 22:43:17.737 RACDemo[46034:5333662] 控制器知道:点击了按钮
代替KVO :
-
rac_valuesAndChangesForKeyPath
:用于监听某个对象的属性改变。 -
方法调用者:就是被监听的对象。
-
KeyPath:监听的属性。
-
把监听redV的center属性改变转换成信号,只要值改变就会发送信号。
-
observer
:可以传入nil。
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor randomColor];
Cat *cat = [Cat new];
self.cat = cat;
[[self.cat rac_valuesAndChangesForKeyPath:@"age" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.cat.age += 1;
}
2016-03-21 10:18:26.130 RACDemo[46460:5399402] <RACTuple: 0x17400e460> (
5,
{
kind = 1;
new = 5;
}
)
监听事件:
-
rac_signalForControlEvents
:用于监听某个事件。 -
把按钮点击事件转换为信号,点击按钮,就会发送信号。
[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"按钮被点击了");
}];
2016-03-21 10:34:02.781 RACDemo[46512:5404121] 按钮被点击了
代替通知:
-
rac_addObserverForName:用于监听某个通知。
-
只要发出这个通知,又会转换成一个信号。
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
NSLog(@"弹出键盘");
}];
2016-03-21 10:42:13.226 RACDemo[46545:5406463] 弹出键盘
监听文本框文字改变:
-
rac_textSignal
:只要文本框发出改变就会发出这个信号。 -
获取文本框文字改变的信号。
[self.textfield.rac_textSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
2016-03-21 10:45:44.464 RACDemo[46557:5407311] r
2016-03-21 10:45:44.743 RACDemo[46557:5407311] rr
2016-03-21 10:45:44.960 RACDemo[46557:5407311] rrh
liftSelector
-
需求:处理当界面有多次请求时,需要都获取到数据时,才能展示界面。
-
rac_liftSelector:withSignalsFromArray:Signals:
当传入的Signals(信号数组),每一个signal都至少sendNext
过一次,就会去触发第一个selector
参数的方法。 -
使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
-
不需要主动订阅signalA和signalB,方法内部会自动订阅。
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor randomColor];
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[subscriber sendNext:@"A"];
});
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B"];
[subscriber sendNext:@"Another B"];
[subscriber sendCompleted];
return nil;
}];
[self rac_liftSelector:@selector(doA:withB:) withSignals:signalA, signalB, nil];
}
- (void)doA:(NSString *)A withB:(NSString *)B {
NSLog(@"A:%@ and B:%@", A, B);
}
2016-03-21 11:11:17.527 RACDemo[46668:5415565] A:A and B:Another B
RAC常见宏
RAC(TARGET, [KEYPATH, [NIL_VALUE]])
-
用于给某个对象的某个属性绑定。把一个对象的某个属性绑定一个信号,只要发出信号,就会把信号的内容给对象的属性赋值。
-
实现了label的内容跟随textField内容的改变而改变。
RAC(self.label, text) = self.textField.rac_textSignal;
RACObserve(self, name)
-
用于给某个对象的某个属性绑定。
-
快速的监听某个对象的某个属性改变。
-
返回的是一个信号,对象的某个属性改变的信号。
[RACObserve(self.view, center) subscribeNext:^(id x) {
NSLog(@"%@", NSStringFromCGRect(self.textField.frame));
}];
2016-03-21 11:25:47.710 RACDemo[46722:5419085] { {198, 156}, {205, 30} }
RACTuplePack和RACTupleUnpack
-
RACTuplePack
:把数据包装成RACTuple(元组类)。把包装的类型放在宏的参数里面,就会自动包装。 -
RACTupleUnpack
:把RACTuple(元组类)解包成对应的数据。等号的右边表示解析哪个元组。宏的参数:表示解析成什么类型。
RACTuple *tuple = RACTuplePack(@1,@3);
NSLog(@"%@", tuple);
RACTupleUnpack(NSNumber *num1,NSNumber *num2) = tuple;
NSLog(@"%@ %@", num1, num2);
2016-03-21 11:28:32.712 RACDemo[46736:5420042] <RACTuple: 0x17400c4d0> (
1,
3
)
2016-03-21 11:28:32.713 RACDemo[46736:5420042] 1 3
代码:
文章中的代码都可以从我的GitHub RACDemo
找到。