代码之家  ›  专栏  ›  技术社区  ›  Harsh.C

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

  •  0
  • Harsh.C  · 技术社区  · 10 年前

    我正在使用googleplacesapi获取用户附近商店的详细信息。我从呼叫中得到的响应显示在表格视图中。我进行了两次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,它是保存数据的字典。现在,在显示表视图的类中,我从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 回复  |  直到 10 年前
        1
  •  1
  •   Markus    10 年前

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

    推荐文章