Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sendAsynchronousRequest with tableView reloadData delay on draw

I'm trying to use the new sendAsynchronousRequest added in iOS5. I have a model class (File) with a method that request some data from a server, and then pass this data to the controller class (FilesController) that created the model object.

The model class has a method with the next code:

[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);
}];

The controller class, uses it like this:

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

    NSLog(@"set");

    [self.tableView reloadData];

    NSLog(@"reload");

    activityIndicator.hidden = TRUE;
}];

In the console I can view immediately how the NSLogs shows the "set" and "reload" messages, but the table and the indicator doesn't change until some seconds (5-10s) have passed.

Somebody knows where is the problem?

Thanks.

PD: I changed the async request with a compatible synched one, and then the problem dissapear but want to use an async request for this.

This is the compatible sync code:

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);
like image 201
Javier Martinez Fernandez Avatar asked Nov 17 '11 15:11

Javier Martinez Fernandez


1 Answers

you need to do [tableView reloadData] on the main thread. All UI operations must be done on the main thread. Multiple ways to do this. One is:

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

EDIT: added activityIndicator to example

like image 111
XJones Avatar answered Nov 15 '22 05:11

XJones