更新异步HTTP请求的completionHandler中的视图时出现延迟

Tia*_*ago 3 objective-c nsurlconnection uialertview ios

在当用户按下一个按钮我的应用程序我开始一个HTTP异步请求(使用[NSURLConnection sendAsynchronousRequest...])和改变的文本UILabel中的completionHandler块.但是,当请求结束时,这种变化不会发生,而是在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];
     }];    
}
Run Code Online (Sandbox Code Playgroud)

当我尝试在UIAlertView内部创建内部时,会发生类似的行为completionHandler.

- (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];
         }
     }];    
}
Run Code Online (Sandbox Code Playgroud)

但是,一个小的区别是屏幕在[alert show]执行时会变暗.警报本身仅在2-3秒后出现,就像上一个场景一样.

我猜这与应用程序的线程如何处理UI有关,但我不确定.任何有关延迟发生原因的指导将不胜感激.

iOS*_*com 9

根据The Apple Docs.

线程和您的用户界面

如果您的应用程序具有图形用户界面,建议您从应用程序的主线程接收与用户相关的事件并启动界面更新.此方法有助于避免与处理用户事件和绘制窗口内容相关的同步问题.某些框架(如Cocoa)通常需要此行为,但即使对于那些不这样做的框架,将此行为保留在主线程上也具有简化管理用户界面的逻辑的优势.

在主线程上调用UI更新可以解决此问题.通过调用主线程(下面)来围绕UI代码.

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

还有其他方法可以对主线程进行调用,但使用更简单的GCD命令可以完成这项工作.再次,请参阅" 线程编程指南"以获取更多信息.