在asynchronousHTTP请求的completionHandler中更新视图时延迟

在我的应用程序中,当用户按下一个button时,我开始一个HTTPasynchronous请求(使用[NSURLConnection sendAsynchronousRequest...] ),并在completionHandler块中更改UILabel的文本。 然而,这一变化在请求结束时不会发生,而是在2-3秒后发生。 下面是导致这种行为的代码片段。

 - (IBAction)requestStuff:(id)sender { NSURL *url = [NSURL URLWithString:@"http://stackoverflow.com/"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; exampleLabel.text = [NSString stringWithFormat:@"%d", httpResponse.statusCode]; }]; } 

当我尝试在completionHandler创build一个UIAlertView时,会发生类似的行为。

 - (IBAction)requestStuff:(id)sender { NSURL *url = [NSURL URLWithString:@"http://stackoverflow.com/"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if ([httpResponse statusCode] == 200) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"It worked!" message:nil delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } }]; } 

但是,一个小的区别是当执行[alert show]时屏幕会变暗。 警报本身只在2-3秒之后出现,就像以前的情况一样。

我猜这与用户界面是如何处理的应用程序的线程有关,但我不确定。 任何指导为什么延迟发生将不胜感激。

根据苹果文件 。

线程和您的用户界面

如果您的应用程序具有graphics用户界面,则build议您接收用户相关事件并从应用程序的主线程启动界面更新。 这种方法有助于避免与处理用户事件和绘制窗口内容相关的同步问题 。 一些框架,比如Cocoa,通常需要这种行为,但即使对于那些没有的行为,在主线程上保持这种行为也有简化pipe理用户界面的逻辑的优点。

在主线程上调用UI更新可以解决这个问题。 用主线程调用你的UI代码(在下面)。

 dispatch_async(dispatch_get_main_queue(), ^{ exampleLabel.text = [NSString stringWithFormat:@"%d", httpResponse.statusCode]; }); 

还有其他方法可以在主线程上进行调用,但使用更简单的GCD命令可以完成这项工作。 再次请参阅“ 螺纹编程指南”了解更多信息。

这可能发生,因为所有UI的东西应该在主队列中调用。 尝试这个:

 - (IBAction)requestStuff:(id)sender { NSURL *url = [NSURL URLWithString:@"http://stackoverflow.com/"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; dispatch_async(dispatch_get_main_queue(), ^{ exampleLabel.text = [NSString stringWithFormat:@"%d", httpResponse.statusCode]; }); }]; } 

您可以尝试创build一个设置文本的方法,并在您要调用的块内:

  [self performSelectorOnMainThread:@selector(mySelector) withObject:nil waitUntilDone:NO]; 

select器将在主线程上调用并执行。 希望这个帮助….