ios - 使用 ReactiveCocoa 在模型更新时查看 Controller 状态更新

标签 ios reactive-cocoa

当我慢慢地尝试围绕 ReactiveCocoa 进行思考时,我编写了这段代码,并且我相当确定有更好的方法来解决我的问题。我非常感谢有关如何改进/重新设计我的情况的意见。

@weakify(self);

[RACObserve(self, project) subscribeNext:^(MyProject *project) {
    @strongify(self);
    self.tasks = nil;
    [[[project tasks] takeUntilBlock:^BOOL(NSArray *tasks) {
        if ([tasks count] > 0) {
            MyTask *task = (MyTask *)tasks[0];
            BOOL valid = ![task.projectID isEqualToString:self.project.objectID];
            return valid;
        }
        return NO;
    }] subscribeNext:^(NSArray *tasks) {
        self.tasks = tasks;
    }];
}];

这是做什么的:

我有一个 View Controller,它有一个名为 projectMyProject 属性和一个 tasks NSArray 属性>。一个项目有一个 tasks 信号,它返回一个 MyTask 数组。可以随时从外部更改项目。我希望我的 View Controller 在上述情况发生时做出响应并自行刷新。

我要解决的问题:

我曾经在第一个 block 中[[project tasks] subscribeNext:...],直到我意识到如果 webrequest 花费的时间太长并且我同时切换了项目,我收到并在新环境中分配旧项目的数据! (此后不久,新数据集到达,一切恢复正常)。

不过,这就是我遇到的问题,我通过使用 takeUntilBlock: 方法解决了它。我的问题是:我如何简化/重新设计它?

最佳答案

最自然地接管最近项目任务的关键运算符是 -switchToLatest .此运算符获取信号中的一个信号并返回一个信号,该信号仅发送从最新信号发送的值。

如果这听起来太抽象,将它放在您的领域中会有所帮助。首先,您有一个项目信号,特别是 RACObserve(self, project)。然后,您可以将此项目信号 -map: 转换为包含调用 -tasks 的结果的信号,这恰好会返回一个信号。现在你有一个信号的信号。将 -switchToLatest 应用于任务信号的信号将为您提供任务信号,但只会发送来自最近项目的任务,而不会发送来自先前分配项目的“旧”任务。

在代码中,这看起来像:

[[RACObserve(self, project)
    map:^(MyProject *project) {
        return [project tasks];
    }]
    switchToLatest];

另一个可以用来简化代码的习惯用法是使用 RAC() 宏,它分配给一个属性,同时避免显式订阅。

RAC(self, tasks) = [[RACObserve(self, project)
    map:^(MyProject *project) {
        return [project tasks];
    }]
    switchToLatest];

更新

为了解决评论中的问题,这里有一个示例,说明如何在项目更改后将 tasks 属性初始化为 nil,以及一种简单的方法处理 -tasks 信号中的错误。

RAC(self, tasks) = [[RACObserve(self, project)
    map:^(MyProject *project) {
        return [[[project
            tasks]
            startsWith:nil]
            catch:^(NSError *error) {
                [self handleError:error];
                return [RACSignal return:nil];
            }];
    }]
    switchToLatest];

关于ios - 使用 ReactiveCocoa 在模型更新时查看 Controller 状态更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20850873/

相关文章:

iOS 应用内购买内容集成

ios - 如何在自动布局中更改选择器 View 的字体大小

cocoa - 如何在调用 API 之前使用 ReactiveCocoa 进行透明身份验证?

ios - 使用 ReactiveCocoa 将 UISwitch 的状态绑定(bind)到模型

ios - @strongify(self.delegate)不工作

swift - 如何扩展ReactiveCocoa4的SignalProducerType

ios - 没有iPhone 5s设备时如何测试Touch ID功能

ios - 一段文本中每个单词的音频

ios - 在 GCD 中,何时使用全局并发队列与自定义并发队列?

reactive-cocoa - ReactiveCocoa - 如果第一个信号完成且没有任何值,则订阅第二个信号