0

我正在使用以下代码设置一个属性,该属性在核心数据记录中保存有关 twitter 速率限制的信息:

- (Limits *)limits
{
    if (!_limits) {
        [[[TwitterManager sharedManager] API] getRateLimitsForResources:nil successBlock:^(NSDictionary *rateLimits) {
            _limits = [Limits createWithInfo:rateLimits user:_user];
        } errorBlock:^(NSError *error) {
            NSLog(@"Error %s: %@", __PRETTY_FUNCTION__, error);
        }];
    }
    return _limits;
}

当它到达最后一行时,它不会反映新值,因为该块尚未完成。我怎样才能最好地解决这个问题?

4

1 回答 1

0

像这样混合同步和异步代码是相当困难的。进行此操作的最佳方法是使您的limits方法异步并使其具有完成块:

- (void)getLimits: (void (^)( Limits *limits ))block
{
      if (_limits) {
         block( _limits );
      } else {
         [[[TwitterManager sharedManager] API] getRateLimitsForResources:nil successBlock:^(NSDictionary *rateLimits) {
            _limits = [Limits createWithInfo:rateLimits user:_user];
            block( _limits );
         } errorBlock:^(NSError *error) {
            NSLog(@"Error %s: %@", __PRETTY_FUNCTION__, error);
            block( nil );
         }];
      }
}

如果你想在主线程上调用你的 limits 方法,你真的应该使用这个选项。阻塞网络访问的主线程不会带来很好的用户体验,如果请求时间过长,可能会让你的应用程序被看门狗杀死。

如果这不是一个选项,您基本上必须等待请求完成。如果您的 TwitterManager 支持,最简单的方法是使用同步方法。如果不是,则有不同的方法来处理此问题,具体取决于 TwitterManager 类的实现方式。

如果一切都在不同的线程上运行,你可以使用一个调度组来阻塞你当前的线程,直到响应到达(dispatch_group_wait)。如果您的 twitter 类尝试在您发送消息的同一队列/线程上分派任何工作,这将导致死锁limits

于 2014-03-02T11:28:17.740 回答