在我的应用程序中,当用户按下一个按钮时,我启动一个HTTP异步请求(使用AFURLConnectionOperation)并更改completionHandler块中的UILabel文本。但是,此更改不会在请求结束时发生,而是在2-3秒后发生。下面是导致此行为的代码段。
AFURLConnectionOperation* operation = ...
[opration setCompletionBlock:^{
NSLog(@"This text appears immediatly");
[myLabel setText:@"this one is delayed for 2-3 sec"];
}];
[opreation start];tahnks求助
发布于 2013-09-09 20:06:26
这是试图尝试从后台队列执行UI更新的症状。如果将UI更新添加回主队列,您的问题将得到解决:
[operation setCompletionBlock:^{
NSLog(@"This text appears immediately");
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[myLabel setText:@"this should not be delayed for 2-3 sec"];
}];
}];正如NSOperation documentation for setCompletionBlock所说,您无法保证完成操作将发生在哪个线程上:
未保证完成块的确切执行上下文,但通常是次要线程。因此,您不应该使用这个块来执行任何需要非常特定的执行上下文的工作。相反,您应该将该工作分流到应用程序的主线程或能够执行该工作的特定线程。..。
UI更新必须在主队列上进行,因此如果您的完成块想要执行UI更新,它必须显式地将它们添加到主队列中。
发布于 2013-09-09 20:11:38
AFURLConnectionOperation是NSOperation的子类。
此外,通过查看AFURLConnectionOperation.m,我们可以看到setCompletionBlock:基本上只是调用它的超级方法(当然,它还负责处理locking,并在完成后很好地将completionBlock属性设置为nil )。
重要注意事项:AFURLConnectionOperation不会在主线程上为您执行completionBlock。NSOperation也不能保证在主线程上执行completionBlock。
但是,用户界面(UI)更新必须在主线程上发生(否则,可能会发生意外的事情)。
要解决这个问题,您需要确保UI更新是在主线程上进行的。例如,您可以这样做:
[operation setCompletionBlock:^{
NSLog(@"This text appears immediately");
dispatch_async(dispatch_get_main_queue(), ^{
// do your UI updates here...
});
}];https://stackoverflow.com/questions/18705684
复制相似问题