使用nsurlsessiontask导致表视图中的数据显示不正确并且更改将滚动

时间:2016-04-19 18:40:51

标签: ios uitableview nsurlsession nsurlsessiondatatask

我正在使用google places api获取有关用户附近商店的详细信息。我从通话中得到的回应,我在表格视图中显示。我打两个api电话。一个电话找到附近的商店,另一个电话获取有关每个返回的商店的信息,如网址,电话号码,图片等。所以我首先在主线程上进行了这两个调用,这减缓了我的用户界面。滚动时表格视图滞后很多(但所有单元格都有正确的数据,向上或向下滚动时数据没有变化)。然后我决定使用nsurlsessiontask来执行两个api调用,这样就不会减慢UI的速度。这是代码:

首先是api电话:

s1 = @"Http request";
NSURL *jsonURL = [NSURL URLWithString:[self urlEncodeValue:s1]];
NSString *jsonDataString  = [[NSString alloc]initWithContentsOfURL:jsonURL];

NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:jsonURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (data == nil || error != nil) {
        NSLog(@"error: %@", error);
        return;
    }

    NSError *parseError;
    self.jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
    if (self.jsonDict) 
   {
      //perform taks
   }

所以基本上我创建并初始化了jsonDict,它是保存数据的字典。现在在我的类中显示tableview,我从jsonDict获取数据并将其显示在单元格中。例如:

cell.addresslabel = [[[appDelegate.jsonDict objectForKey@"results"] objectAtIndex:indexPath.row] objectForKey:@"address"];

为了获取商店的电话号码和网站,我需要另外发出http请求。所以我在显示tableView的同一个类中创建了一个方法。这是代码:

s2 = @"Second http request"
NSURL *jsonURL = [NSURL URLWithString:s2];

NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:jsonURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (data == nil || error != nil) {
        NSLog(@"error: %@", error);
        return;
    }

    NSError *parseError;
    phoneDic = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
    if (phoneDic) {
       //perform tasks
    } else {
        NSLog(@"parseError: %@", parseError);
        NSLog(@"responseString: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }
}];
[task resume];

因此,当我这样做时,表格视图不会“滞后”,但显示的数据不正确(单元格显示其他单元格的数据),当我向上或向下滚动数据更改时?所以当我在主线程上执行任务时有滞后但是显示正确的数据,当我使用nsurlsessiontask时没有滞后但是显示的数据不正确。我对nsurlsessiontask做错了什么?

1 个答案:

答案 0 :(得分:1)

问题的原因是,一旦NSURLSessionTask完成,单元格可能会在完全不同的位置重用。在cellForRowAtIndexPath中将单元格出列后,可以停止先前运行的任务并重新启动新任务。理想情况下,数据请求任务与UITableView中的表示分开完成,包括缓存接收的数据。