首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解RACSignal误差

理解RACSignal误差
EN

Stack Overflow用户
提问于 2014-03-04 08:03:57
回答 2查看 1.7K关注 0票数 3

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

不管怎么说,这是我已经想出来的。

我将NSArray属性绑定到RACSignal,以便能够通过网络对传入的JSON数据作出反应。

代码语言:javascript
复制
- (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;
    }];
}

信号创建如下所示:

代码语言:javascript
复制
- (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]);
    }];

}

现在,当web服务不提供任何数据时,我想对此作出反应。现在,这个应用程序崩溃了,下面的声明我真的不明白:

*终止应用程序,原因是:“接收到的名称错误:[+createSignal:-doError:] -doNext:在键路径上绑定”用户“on:(null)‘

我在这里错过了什么?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-04 18:52:36

接受的答案可以解决这个问题,但是有一种更地道、更优雅的方法来处理这个问题:

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
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 *的方法。

票数 11
EN

Stack Overflow用户

发布于 2014-03-04 08:37:45

  1. 通过编写RAC(self, users),意味着您希望将信号的返回绑定到属性users,但在信号处理程序中没有返回任何内容。
  2. 您使用的是doNext,它是当前信号的注入。你可能想订阅它,而不是注射副作用。

解决:

如果要在RAC(self, users)副作用中指定它,可以删除subscribeNext绑定,所以只需订阅信号就可以了,如下所示:

代码语言:javascript
复制
@weakify(self);
[[self fetchRandomUserData] subscribeNext:^(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;
}];
票数 -4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22166175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档