0

Google Places API を使用して、ユーザーの近くの店舗に関する詳細を取得しています。呼び出しから得た応答をテーブル ビューに表示します。2 つの 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 に何か問題がありますか?

4

1 に答える 1

1

問題の理由は、NSURLSessionTask が完了すると、セルがまったく別の位置で再利用される可能性があるためです。cellForRowAtIndexPath でセルをデキューすると、以前に実行していたタスクを停止して、新しいタスクを再開できます。理想的には、データ要求タスクは、受信したデータのキャッシュを含め、UITableView でのプレゼンテーションとは別に実行されます。

于 2016-04-20T08:05:22.297 に答える