ReactiveCocoa的常见操作

这篇主要是举出示例,演示rac的常见基础操作。加深理解,灵活使用到项目中,使代码更加的茁壮优雅。也当是关于rac的使用笔记。

RAC/RACObserve宏的使用

[[RACObserve(self, userName) skip:1] subscribeNext:^(NSString *x) {
    NSLog(@"%@", x);
}];

RAC(self, textLabel.text) = RACObserve(self, userName);

订阅UI控件的信号

[[[[_textField.rac_textSignal skip:1] filter:^BOOL(NSString *value) {
    return value.length <= 10;
}] map:^id _Nullable(NSString * _Nullable value) {
    return [NSString stringWithFormat:@"%@%@", value, value];
}] subscribeNext:^(NSString *x) {
    self.userName = x;
}];

信号队列的处理

NSArray *array = @[@"A",@"B",@"C"];
    
[[[[[[array.rac_sequence.signal delay:8] doNext:^(id x) {
    NSLog(@"doNext:%@", x);
}]then:^RACSignal *{
    return @[@"1", @"2", @"3", @"4", @"5"].rac_sequence.signal;
}] filter:^BOOL(id value) {
    NSLog(@"filter:%@", value);
    return [value integerValue] % 2;
}] map:^id(id value) {
    value = @(pow([value integerValue], 3.0f));
    return value;
}]subscribeNext:^(id x) {
    NSLog(@"subscribeNext: %@",x);
}];
//output:
doNext:A
doNext:B
doNext:C
filter:1
subscribeNext: 1
filter:2
filter:3
subscribeNext: 27
filter:4
filter:5
subscribeNext: 125

订阅协议protocal

_inputTextView.delegate = self;
[[self rac_signalForSelector:@selector(textViewDidChange:) fromProtocol:@protocol(UITextViewDelegate)] subscribeNext:^(RACTuple * _Nullable x) {
    UITextView *textView = x.first;
    NSLog(@"%@", textView.text);
}];

订阅Notification通知

//监听键盘的弹起收回事件
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
    NSLog(@"keyboard show");
}];

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillHideNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
    NSLog(@"keyboard hide");
}];

信号拼接concat

//信号的前后衔接拼接
// A:  a b c
// B:  d e f g
// concat:  a b c d e f g
RACSequence *rice = @[@"米饭", @"粥"].rac_sequence;
RACSequence *meat = @[@"猪肉", @"牛肉"].rac_sequence;

RACSequence *merge_rice_meat = [rice concat:meat];

NSArray *concatArray = [[merge_rice_meat map:^id _Nullable(id  _Nullable value) {
    NSLog(@"我吃了%@", value);
    return value;
}] array];

NSLog(@"%@", concatArray);

//output:
我吃了米饭
我吃了粥
我吃了猪肉
我吃了牛肉

信号合并merge

//按照信号的前后到达的顺序合并。
RACSubject *cola = [RACSubject subject];

RACSubject *water = [RACSubject subject];

RACSignal *merge_cola_water = [RACSignal merge:@[cola, water]];

[merge_cola_water subscribeNext:^(NSString *x) {
    NSLog(@"我喝了%@", x);
}];

//output: 可乐,雪碧,纯净水,农夫山泉,果粒橙
[cola sendNext:@"可乐"];
[cola sendNext:@"雪碧"];
[water sendNext:@"纯净水"];
[water sendNext:@"农夫山泉"];
[cola sendNext:@"果粒橙"];

//output:
我喝了可乐
我喝了雪碧
我喝了纯净水
我喝了农夫山泉
我喝了果粒橙

多个信号融合combineLatest

多个信号的混合使用,比如只有当用户输入账户、密码,验证码后,才让登录按钮变成可以点击的状态。就可以使用CombineLatest:reduce:来实现。

RACSignal *sugarSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"糖"];
    return nil;
}];
RACSignal *waterSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"水"];
    [subscriber sendNext:@"果"];
    return nil;
}];

[[RACSignal combineLatest:@[sugarSignal, waterSignal] reduce:^id (NSString* sugar, NSString*water){
    return [sugar stringByAppendingString:water];
}] subscribeNext:^(id x) {
    NSLog(@"CombineLatest第一种:%@", x);
}];

[[RACSignal combineLatest:@[sugarSignal, waterSignal]] subscribeNext:^(RACTuple* x) {
    RACTupleUnpack(NSString *sugar, NSString *water) = x;
    NSLog(@"CombineLatest第二种:%@%@", sugar, water);
}];

//output:
CombineLatest第一种:糖水
CombineLatest第一种:糖果
CombineLatest第二种:糖水
CombineLatest第二种:糖果
RACSubject *subject1 = [RACSubject subject];
RACSubject *subject2 = [RACSubject subject];

[[RACSignal combineLatest:@[subject1, subject2] reduce:^(NSString *str1, NSString *str2){
    NSString *combineString = [NSString stringWithFormat:@"%@%@", str1, str2];
    return combineString;
}] subscribeNext:^(id x) {
    NSLog(@"融合以后>%@",x);
}];

[subject1 sendNext:@"ABCD后面是"];
[subject2 sendNext:@"EFG"];
//output:
融合以后>ABCD后面是EFG

信号可重复订阅replay

RACSignal *replaySignal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"导演只拍了一次电影《变形金刚》。");
    [subscriber sendNext:@"《变形金刚》"];
    return nil;
}] replay];
[replaySignal subscribeNext:^(id x) {
    NSLog(@"小明看了%@", x);
}];
[replaySignal subscribeNext:^(id x) {
    NSLog(@"小红也看了%@", x);
}];

//output:
导演只拍了一次电影《变形金刚》。
小明看了《变形金刚》
小红也看了《变形金刚》

信号定时执行

__block NSInteger value = 9999;
[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
    value--;
    NSLog(@"倒计时%ld", value);
}];

//output:
倒计时9998
倒计时9997
倒计时9996
倒计时9995
倒计时9994
倒计时9993
倒计时9992
......
......

命令RACCommand

RACCommand *aCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    NSLog(@"发布命令:%@", input);
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"命令执行");
        [subscriber sendCompleted];
        return nil;
    }];
}];
[aCommand execute:@"fight"];

//output:
发布命令:fight
命令执行

Cell里面使用ReactiveCocoa

在UITableView的Cell中使用rac给按钮增加监听的时候,需要使用takeUntil:self.rac_prepareForReuseSignal,否则会因为Cell的重用,导致按钮的监听出问题。

[[[self.cancelButton rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(UIButton *x) { 
    // do other things 
}];

文章来自 http://skymonkey.cn/

高能广告区

暂无广告哦=^^=。继续看看其它文章吧!