2011-11-17 53 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