2011-11-17 49 views
5

我试图使用在iOS5中添加新的sendAsynchronousRequest。 我有一个模型类(文件)的方法,从服务器请求一些数据,然后将此数据传递到控制器类(FilesController),创建该模型对象。sendAsynchronousRequest与tableView reloadData延迟绘制

模型类具有与下一个代码的方法:

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
    NSArray *decodedResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; 
    NSArray *files = [self _dictionariesToFiles:decodedResponse]; 
    handler(files); 
}]; 

控制器类,使用这样的:

[File findAll:conditions completionHandler:^(NSArray *files) { 
    dataSource = files; 

    NSLog(@"set"); 

    [self.tableView reloadData]; 

    NSLog(@"reload"); 

    activityIndicator.hidden = TRUE; 
}]; 

在控制台我可以立即查看NSLogs如何示出了“设置”和“重新加载”消息,但表格和指示符在数秒(5-10秒)过去之后才会改变。

有人知道问题在哪里?

谢谢。

PD:我使用兼容的同步请求更改了异步请求,然后问题消失,但希望为此使用异步请求。

这是兼容的同步代码:

NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
NSArray *decodedResponse = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil]; 
NSArray *files = [self _dictionariesToFiles:decodedResponse]; 
handler(files); 

回答

16

你需要在主线程上做[tableView reloadData]。所有UI操作必须在主线程上完成。多种方式来做到这一点。其一是:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.tableView reloadData]; 
    activityIndicator.hidden = TRUE; 
}); 

编辑:添加activityIndi​​cator例

3

我也有几个问题使用:[[NSOperationQueue alloc] init]但使用[NSOperationQueue mainQueue]一切都是完美的。使用新队列执行线不遵循自然序列

+2

这是因为mainQueue在主线程上运行,这是所有UI东西都必须发生的地方。 – greenisus

+0

@Rscorreia greenisus是正确的我有同样的问题,直到我发现这一点。 –

+0

@greenisus那么,你如何才能获得异步请求,然后快速工作呢?如果你这样做'''[NSOperationQueue mainQueue]'''它把它放在主线程上,这首先破坏了使用异步请求的目的....“ – Supertecnoboff