我正在使用以下代码设置一个属性,该属性包含有关核心数据记录中的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;
}
当它到达最后一行时,它不会反映新值,因为块尚未完成。我怎么能最好地解决这个问题?
答案 0 :(得分: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 );
}];
}
}
如果你想在主线程上调用你的限制方法,你真的应该选择这个选项。阻止主线程进行网络访问不会带来出色的用户体验,并且如果请求时间过长,可能会使监视程序将您的应用程序杀死。
如果这不是一个选项,你基本上必须等待请求完成。最简单的方法是在TwitterManager支持的情况下使用同步方法。如果没有,则有不同的方法来处理这个问题,具体取决于TwitterManager类的实现方式。
如果所有内容都在不同的线程上运行,您可以使用调度组来阻止当前线程,直到响应到达(dispatch_group_wait
)。如果您的twitter类尝试在您发送limits
消息的同一队列/线程上发送任何工作,这将导致死锁。