iOS学习笔记

RAC在项目中的初步应用

2017-06-09  本文已影响0人  isletn

首先简单介绍一下RAC是个什么东西。RAC全称ReactiveCocoa,是GitHub开源的一个函数响应式编程(FRP)库。

Signal 与 Subscriber

可以说这是RAC核心最核心的两个概念。Signal好比是光纤中传输的数字信号,而Subscriber是我们每个人家里的光猫。我们打开了家里的光猫才能正常上网,Signal 与 Subscriber就是这个互相配合工作的。

首先我们看看RACSubscriber的API

@protocol RACSubscriber <NSObject>
@required
- (void)sendNext:(nullable id)value;
- (void)sendError:(nullable NSError *)error;
- (void)sendCompleted;
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;
@end

Subscriber通过sendNext、sendError、sendCompleted等方法获取由Signal传输过来的数据。用法如下:

RACSignal *signal = RACObserve(self, clueArray);
[signal subscribeNext:^(id  _Nullable x) {
     NSLog(@"%@",x);
}];

上述例子我们监听了一个全局变量数组,在它发生变化时我们可以做自己想做的操作,比如更新UI、给服务器上传数据变化等等。

这里就暂时初步做个介绍吧, 深入的理解等我搞清楚了在写吧,本篇只介绍简单的用法。

RAC实用的API:

[[self.confirmButton rac_signalForControlEvents:UIControlEventTouchUpInside]
  subscribeNext:^(id x) {
  // 回调内容写在这里
  }];
[[self.scrollView rac_signalForSelector:@selector(scrollViewDidScroll:) fromProtocol:@protocol(UIScrollViewDelegate)]
  subscribeNext:^(id x) {
  // 回调内容写在这里
  }];
[[self asyncProcess] subscribeNext:^(id x) {
  // 回调内容写在这里
  } error:^(NSError *error) {
  // 错误处理写到这里
  }];
//订阅通知
@weakify(self)
    [[[kNotificationCenter rac_addObserverForName:kOperateReturnNotificationNameUpdate object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification * _Nullable x) {
        @strongify(self)
        [self fetchData];
    }];
[RACObserve(self, name) subscribeNext:^(id x) {
  // 回调内容写在这里
  }];
//当两个TextField的text长度都大于零,确认按钮才能点击
RAC(self.confirmItem, enabled) = [RACSignal combineLatest:@[self.userNameTextField.rac_textSignal,
                                                                self.passwordTextField.rac_textSignal,]
                                                       reduce:^id _Nullable{
                                                           return @(self.userNameTextField.text.length > 0 && self.passwordTextField.text.length > 0);
                                                       }];
//Model与View互相影响。当textField的text改变,model对应的值也跟着改变。反之,也成立。
RACChannelTo(self.someLabel, text) = RACChannelTo(self.viewModel, someProperty);
[self.textField.rac_newTextChannel subscribe:self.viewModel.someChannel];
[self.viewModel.someChannel subscribe:self.textField.rac_newTextChannel];
RACChannelTo(self, reviewID) = self.viewModel.someChannel;

这里就列举以上几种,初步了解一下。


RAC中常见的几个宏

//用于监听person对象的name属性
RACObserve(self.person, name)
//将self.nameLabel.text 与 self.person.name绑定
 RAC(self.nameLabel, text) = RACObserve(self.person, name);
//防止循环引用
@weakify(self)
    [[[kNotificationCenter rac_addObserverForName:kOperateReturnNotificationNameUpdate object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification * _Nullable x) {
        @strongify(self)
        [self fetchData];
    }];

虽然一般公司的项目都不那么复杂,用不上RAC,但是RAC作为一个工具库,也能提供一些比较便捷的解决问题的方案,所以了解一些RAC的知识还是有必要的。
另外,MVVM解决了Controller臃肿的弊病,但也出现了一些新的问题。而MVVM+RAC完美的解决了这些问题,这也体现出RAC的强大。

最后,附上一个MVVM场景下RAC的使用实例:

  + (RACSignal *)fetchData {
        RACReplaySubject *subject = [RACReplaySubject subject];
        NSURLRequest *request = [self popularURLRequest];
        [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError){
                               if (data) {
                                   id results = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                                   [subject sendNext:[[[results[@"photos"] rac_sequence] map:^id(NSDictionary *photoDictionary) {
                                       FRPPhotoModel * model = [FRPPhotoModel new];
                                       [self configurePhotoModel:model withDictionary:photoDictionary];
                                       [self downloadThumbnailForPhotoModel:model];
                                       return model;
                                   }] array]];
                                   [subject sendCompleted];
                               } else {
                                   [subject sendError:connectionError];
                               }
                           }];
    return subject;
}
@weakify(self);
[RACObserver(self, dataArray) subscribeNext:^(id x){
    @strongify(self);
    [self.tableView reloadData];
}];
 - (void)loadPopularPhotos{
    [[DataViewModel fetchData] subscribeNext:^(id x){
        self.dataArray = x;
    } error:^(NSError * error){
        NSLog(@"%@",error);
    }];
}

想深入学习的同学看这里:

上一篇 下一篇

猜你喜欢

热点阅读