objective-c - 带有 UITableView 的 ReactiveCocoa MVVM

标签 objective-c mvvm reactive-cocoa

我正在使用 ReactiveCocoa 并尝试应用 MVVM。我有一个相当典型的 UITableView 场景,带有用于重新加载数据的刷新控件。

我省略了 UITableDataSource/Delegate 方法,因为这些方法很简单。下面的代码说明了我是如何设计 ViewModel 和 ViewController 以配合在一起的。

ViewModel.h

@property (strong, nonatomic, readonly) RACCommand *getItemsCommand;
@property (strong, nonatomic, readonly) NSArray *items;

ViewModel.m
- (instancetype)init {
    self = [super init];
    if (!self) return nil;

    @weakify(self);
    self.getItemsCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        return [[ItemsDataSource getItems]
                doNext:^(NSArray *items) {
                    @strongify(self);
                    // I actually do a little extra work here such as sorting
                    // the items appropriately for the view.
                    self.items = items;
                }];
    }];

    return self;
}

ViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];

    [self.tableView addSubview:self.refreshControl];

    RACSignal *refreshSignals = [RACSignal merge:@[
        [self.refreshControl rac_signalForControlEvents:UIControlEventValueChanged],
        [RACSignal return:nil]
    ]];

    [refreshSignals
     subscribeNext:^(id x) {
         [self.viewModel.getItemsCommand execute:nil];
     }];

    [RACObserve(self.viewModel, items)
     subscribeNext:^(NSArray *items) {
         [self.tableView reloadData];
     } completed:^{
         [self.refreshControl endRefreshing];
     }];
}

问题/问题
  • completed我打电话的地方endRefreshing永远不会被处决,对于我的一生,我无法弄清楚为什么。
  • 使用公共(public)方法会更好- (RACSignal *)getItems而不是 getItems RAC 命令?
  • 我使用的是 doNext:在 ViewModel 中正确以应用副作用(即项目数组的排序)而不导致额外订阅?
  • 最佳答案

    我建议制作 getItemsCommand使用 -map:对项目数组进行排序和处理。将任何其他副作用工作留在单独的 -doNext: 中完成.一旦您的命令遵循此模式(在 RAC 中更具组合性),您就可以使用 RAC()宏将命令的成品,排序后的数组,分配给 items属性(property)。

    RAC(self, items) = [self.getItemsCommand.executionSignals concat];
    

    RAC 具有对 UIRefreshControl 的内置命令支持。这将启动/停止刷新控制以及命令的启动/停止。你应该发现你可以减少你的UIRefreshControl代码:
    self.refreshControl.rac_command = self.getItemsCommand;
    

    对于表重新加载,您可以执行以下操作:
    [RACObserve(self, items) subscribeNext:^(id _) {
        @strongify(self);
        [self.tableView reloadData];
    }];
    

    希望有帮助。

    关于objective-c - 带有 UITableView 的 ReactiveCocoa MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23203436/

    相关文章:

    objective-c - 在 Objective-C 中从字符串中删除空格

    ios - 如何在 IOS 中从 google drive V3 API 下载 pdf?

    ios - 如何在协议(protocol)中的可选方法中将枚举作为参数传递

    objective-c - 在多个私有(private)框架中实现的 tvos 10 SDK 重复类导致崩溃

    .net - 具有扎实的 WPF/.NET 背景学习 ASP.NET MVC

    ios - 有没有办法让 RACSignal 在出错后继续接收 `next` ?

    silverlight - 当ViewModel属性更改时,如何启动动画?

    c# - WPF中的Count属性的INotifyPropertyChanged?

    objective-c - 以 Swift 方式将 Objective-C block 转换为闭包

    Objective-C self->_ivar 访问显式与隐式 self->