ios - 了解 RACSignal 错误

标签 ios objective-c reactive-cocoa

我目前正在迈出 ReactiveCocoa 的第一步,我经历了一些陡峭的学习曲线来理解原则。

无论如何,这就是我已经想到的。

我将 NSArray 属性绑定(bind)到 RACSignal,以便能够对通过网络传入的 JSON 数据使用react。

- (void)updateRandomUserData 
{
    @weakify(self);
    RAC(self, users) = [[self fetchRandomUserData] doNext:^(NSDictionary *json){
    @strongify(self);
    NSMutableArray *randomUsers = [NSMutableArray array];
        for (NSDictionary *dict in json[@"data"]) {
           BKRandomUser *randomUser = [MTLJSONAdapter modelOfClass:[BKRandomUser class] fromJSONDictionary:dict error:nil];
           [randomUsers addObject:randomUser];
        }

        self.users = randomUsers;
    }];
}

信号创建如下所示:

- (RACSignal *)fetchRandomUserData
{

    return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

      NSURLRequest *request = [NSURLRequest requestWithURL:url];

      AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
      [subscriber sendNext:JSON];
      } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON, NSError *error) {
        [subscriber sendError:error];
      }];

      [operation start];

      return [RACDisposable disposableWithBlock:^{
          [operation cancel];
      }];

      }] doError:^(NSError *error) {
        NSLog(@"error: %@", [error description]);
    }];

现在,当网络服务不提供任何数据时,我想对此使用react。现在应用程序崩溃并显示以下语句,老实说我不明白:

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Received error from name: [[+createSignal:] -doError:] -doNext: in binding for key path "users" on : (null)'

我在这里错过了什么?

谢谢!

最佳答案

公认的答案可以解决这个问题,但有一种更惯用、更优雅的方法来处理这个问题:

首先,不要使用 -doNext:,而是使用 -map: 将您的 JSON 转换为用户数组:

RAC(self, users) = [[self fetchRandomUserData] map:^(NSDictionary *json){
    NSMutableArray *randomUsers = [NSMutableArray array];
    for (NSDictionary *dict in json[@"data"]) {
       BKRandomUser *randomUser = [MTLJSONAdapter modelOfClass:[BKRandomUser class] fromJSONDictionary:dict error:nil];
       [randomUsers addObject:randomUser];
    }

    return randomUsers;
}];

然后,要处理错误,可以使用 -catch::

RAC(self, users) = [[[self fetchRandomUserData] map:^(NSDictionary *json){
    NSMutableArray *randomUsers = [NSMutableArray array];
    for (NSDictionary *dict in json[@"data"]) {
       BKRandomUser *randomUser = [MTLJSONAdapter modelOfClass:[BKRandomUser class] fromJSONDictionary:dict error:nil];
       [randomUsers addObject:randomUser];
    }

    return randomUsers;
}] catch:^(NSError *error) {
    return [RACSignal return:@[]];
}];

在这个例子中,如果发生错误,我们会捕获它并用一个空数组替换它。你可以在那里做任何你想做的事。将其替换为 nil,或者如果您只想忽略整个事情,则将其替换为 +[RACSignal empty]。或者调用另一个返回 RACSignal * 的方法。

关于ios - 了解 RACSignal 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22166175/

相关文章:

swift - 用于表单验证的信号和观察者(Reactive Swift)未按预期工作

ios - 如何在不使用 [RACSignal createSignal] 的情况下返回 RACSignal

iphone - 如何设置最小时间每次都显示为UIDatepicker中的默认时间

ios - UIButton Action 不能快速工作

iphone - 高效地访问数组内的数组

ios - ios TableView List中的三态UIButton

ios - 在 RxSwift 中手动发出事件

ios - 验证服务器是否符合 Apple 的 ATS/TLS 1.2 要求的最佳方式

ios - 如何使用 UIPanGestureRecognizer 旋转图像

objective-c - 使用推送通知时如何处理多个设备?