Search code examples
iosobjective-cnsurlconnection

Why is there a delayed in establishing a connection to a database using NSURLConnection sendAsynchronousRequest?


excuse me for not knowing this, but I would like to know why there is a delay when I try to establish a connection to the database.

I am basically pulling data from a database to display the info back onto a UITableView but there seems to be a delay in the connection establishment.

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self fetchFromDatabase];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    [self fetchFromDatabase];
    
    NSLog(@"FOUR");
}

- (void)fetchFromDatabase
{
    // The URL of the database
    NSURL *url = [[NSURL alloc] initWithString:SDTET_DATABASE_SCHEDULE];
    
    // Establish the connection to the database
    [NSURLConnection sendAsynchronousRequest:[ [NSURLRequest alloc] initWithURL:url] queue:[ [NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
     {
         NSLog(@"ONE !");
     } ];
}

However, the output looks like so:

FOUR

FOUR

ONE !

Why doesn't ONE ! get printed out first?

How can I ensure the connection occurs before the numberOfSections is called, if possible?

Thanks


Solution

  • ONE gets printed last because you are calling an asynchronous method.

    You can follow the flow of the program (which method calls which in what order). If we let our imagination stretch a bit, we could say that when a method is synchronous, it basically "says" to the next line of code to wait for it (the method) to finish. However, if a method is asynchronous, it say "don't wait for me". The URL request method you are using is asynchronous. That means it starts to do its job but nobody waits, the execution of code continues in the next line immediately.

    Asynchronous method in code

    There is a piece in the puzzle that will clarify this more. The request method needs to be fed a completion block as a parameter. Explaining blocks is out of scope here, but you need to understand what block is to fully grasp the solution to your problem. Suffice to say, once this asynchronous method finishes its job (which can be a long time and this is one of the reasons for asynchronous approach really), the block is invoked and executed. Block in the method

    So to answer your last question, you need to trigger a refresh on your table view, which you achieve by calling [self.tableView reloadData]; inside the block. There is a nice logic here, since you know the block is executed ONLY after the asynchronous method concludes its work, you will refresh your table view knowing you have the updated data from db.