user2629744
user2629744

Reputation: 31

NSURLConnection taking a long time

This code loads a table view:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //test data

    NSURL *url =[[NSURL alloc] initWithString:urlString];
    //    NSLog(@"String to request: %@",url);
    [  NSURLConnection
     sendAsynchronousRequest:[[NSURLRequest alloc]initWithURL:url]
     queue:[[NSOperationQueue alloc]init]
     completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
         if([data length] >0 && connectionError ==nil){
             NSArray *arrTitle=[[NSArray alloc]init];
             NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
             arrTitle=    [Helper doSplitChar:[Helper splitChar20] :str];
             self.tableView.delegate = self;
             self.tableView.dataSource = self;
             [self fecthDataToItem:arrTitle];
             [self.tableView  reloadData];
             NSLog(@"Load data success");

         }else if (connectionError!=nil){
             NSLog(@"Error: %@",connectionError);
         }
     }];
    //    arrTitle = [NSArray arrayWithObjects:@"ee",@"bb",@"dd", nil];

}

And it takes 10 - 15s to load. How can I make this faster? . Thanks Rob and rmaddy, problem is solve.

Upvotes: 0

Views: 1357

Answers (1)

Rob
Rob

Reputation: 438287

As rmaddy points out, you must do UI updates on the main queue. Failure to do so will, amongst other things, account for some of the problems you're experiencing.

The queue parameter of sendAsynchronousRequest indicates the queue upon which you want the completion block to run. So, you can simply specify [NSOperationQueue mainQueue]:

NSURLRequest *request = [NSURLRequest requestWithURL:url];

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if([data length] > 0 && connectionError == nil) {
        NSString *str      = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSArray  *arrTitle = [Helper doSplitChar:[Helper splitChar20] :str];
        self.tableView.delegate   = self;
        self.tableView.dataSource = self;
        [self fecthDataToItem:arrTitle];
        [self.tableView reloadData];
    } else if (connectionError!=nil) {
        NSLog(@"Error: %@",connectionError);
    }
}];

Or, if you where doing something slow or computationally expensive/slow within that block, go ahead and use your own background queue, but then dispatch the UI updates back to the main queue, e.g.:

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

    // do something computationally expensive here

    // when ready to update the UI, dispatch that back to the main queue

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

        // update your UI here

    }];
}];

Either way, you should always do UI updates (and probably model updates, too, to keep that synchronized) on the main queue.

Upvotes: 5

Related Questions