【问题标题】:Using nsurlsessiontask causing data in table view to be showed incorrectly and change will scrolling使用 nsurlsessiontask 导致表视图中的数据显示不正确并且更改将滚动
【发布时间】:2016-04-19 18:40:50
【问题描述】:

我正在使用 google places api 来获取用户附近商店的详细信息。我从呼叫中得到的响应显示在表格视图中。我做了两个 api 调用。一次调用查找附近的商店,另一次调用获取有关每个返回商店的信息,例如 url、电话号码、图片等。所以我首先在主线程上进行了这两个调用,它减慢了我的 UI。滚动时表格视图滞后很多(但所有单元格都有正确的数据,并且向上或向下滚动时数据没有改变)。然后我决定使用 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 做错了什么?

【问题讨论】:

  • 你在哪里重新加载了 tableview?
  • 我根本没有重新加载表格视图。如果我在 cellForRowAtIndexPath 末尾调用 [tableView reloadData] ,则没有单元格。我无法在 viewDidLoad 或 viewDidUnload 中执行此操作,因为我使用的是 xib 文件,因此视图只加载和卸载一次。

标签: ios uitableview nsurlsession nsurlsessiondatatask


【解决方案1】:

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

【讨论】:

  • 我没有使用可重新加载的单元格。每个单元格都有不同的标识符。我这样做是因为我知道我最多会有 50 个单元格,所以决定不重复使用单元格。但我明白你的意思。我将尝试单独完成调用,然后创建表格视图。
  • 所以你没有使用dequeueReusableCellWithIdentifier?但是你是如何构造单元对象的呢?可以贴一下 cellForRowAtIndexPath 的代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多