为什么使用NSURLConnection sendAsynchronousRequest建立与数据库的连接有延迟?

时间:2015-02-11 01:13:07

标签: ios objective-c nsurlconnection

请原谅我不知道这一点,但我想知道为什么当我尝试与数据库建立连接时会出现延迟。

我基本上从数据库中提取数据以将信息显示回UITableView,但似乎连接建立有延迟。

- (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 !");
     } ];
}

然而,输出看起来像这样:

  

FOUR

     

FOUR

     

ONE!

为什么没有ONE !首先打印出来?

如果可能,如何在调用numberOfSections之前确保连接发生?

由于

3 个答案:

答案 0 :(得分:3)

ONE最后打印,因为您正在调用异步方法。

您可以按照程序的流程(哪种方法以何种顺序调用)。如果我们让想象力有所延伸,我们可以说当一个方法同步时,它基本上“说”到下一行代码等待它(方法)完成。 但是,如果方法是异步的,它会说“不要等我”。您使用的URL请求方法是异步的。这意味着它开始完成它的工作但没有人等待,代码的执行在下一行立即继续。

Asynchronous method in code

谜题中有一块可以更清楚地说明这一点。请求方法需要以完成块作为参数。解释块在这里超出了范围,但是您需要了解什么块才能完全掌握问题的解决方案。 可以这么说,一旦这个异步方法完成它的工作(这可能是很长时间而且这个真的是异步方法的原因之一),就会调用并执行该块。 Block in the method

因此,要回答上一个问题,您需要在表视图上触发刷新,这是通过调用实现的 块内[self.tableView reloadData]; 。这里有一个很好的逻辑,因为你知道只有在异步方法结束它的工作后才执行该块,你将刷新你的表视图,知道你有来自db的更新数据。

答案 1 :(得分:1)

这是因为它是一个异步请求(意味着它不一定立即发生)。这是计算机科学的一个重要原则,它比Objective-C或iOS开发更大的概念。

在您的情况下,您可以摆脱numberOfSectionsInTableView:中调用的抓取工作,然后只需拨打[self.tableView reloadData]中的completionHandler

答案 2 :(得分:1)

由于网络访问速度缓慢,因此存在延迟。有时候它真的很慢。

有时您可以在不到一秒的时间内得到回复,有时可能需要一分钟的时间来获得回复。

您应始终将网络代码编写为异步,这意味着您使用立即返回的方法提交请求。您的程序继续运行,然后在收到响应后收到通知。

您的代码发生了什么。

您不希望在numberOfSectionsInTableView中发送加载数据的请求。您应该尽早发送网络请求,最好是在显示结果的视图控制器显示之前。

但是,在填充数据之前显示表视图是很常见的。您可能会显示一个空表视图,其中包含数据正在加载的消息,或者带有进度对话框。在其他情况下,您可能知道要显示多少个单元格,并且具有文本数据但不包含图像。在这种情况下,您可以使用占位符图像填充单元格。加载数据后,您可以更新显示。

在您的情况下,您应该编写numberOfSectionsInTableView和numberOfRowsInSection:方法以返回零,然后使网络调用的完成方法告诉表视图重新加载。