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

Using nsurlsessiontask causing data in table view to be showed incorrectly and change will scrolling

我正在使用 google 地点 api 获取用户附近商店的详细信息。我从通话中获得的响应显示在 table 视图中。我打了两个 api 电话。一个是寻找附近的商店,另一个是获取每个返回商店的信息,例如 url、phone 号码、图片等。所以我首先在主线程上进行了这两个调用,速度变慢了我的 UI。 table 视图在滚动时滞后很多(但所有单元格都有正确的数据,并且向上或向下滚动时数据没有改变)。然后我决定使用 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,它是保存数据的字典。现在,在显示 table 视图的 class 中,我从 jsonDict 获取数据并将其显示在单元格中。例如:

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

为了获得商店的 phone 号码和网站,我需要再次发出 http 请求。因此,我在显示 table 视图的 class 中创建了一个方法。这是代码:

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];

所以当我这样做时,table 视图不会 "lag" 但是显示的数据不正确(单元格显示其他单元格的数据)并且当我向上或向下滚动时数据发生变化?因此,当我在主线程上执行任务时,存在延迟但显示正确的数据,当我使用 nsurlsessiontask 时,没有延迟但显示的数据不正确。我对 nsurlsessiontask 做错了什么?

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