我正在使用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做错了什么?
答案 0 :(得分:1)
问题的原因是,一旦NSURLSessionTask完成,单元格可能会在完全不同的位置重用。在cellForRowAtIndexPath中将单元格出列后,可以停止先前运行的任务并重新启动新任务。理想情况下,数据请求任务与UITableView中的表示分开完成,包括缓存接收的数据。