1

HTTPリクエスト(非同期で実行される)を使用して取得したデータを入力したい静的UITableViewがあります。いくつかの場所で HTTP リクエストを作成しようとしましたが、毎回リクエストからのデータの到着が遅すぎて、テーブル ビューにデータが入力されません。テーブルビューにデータを入力する唯一の方法はreloadData、次のように呼び出すことです。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    _accountModel = [[CatapultAccount alloc] init];

    [_accountModel getCurrentClient:^ (BOOL completed, NSDictionary *currentAccount) {
        if (completed) {
            _account = currentAccount;
            [self.tableView reloadData];
        } else {
            UIAlertView *errorMessage = [[UIAlertView alloc] initWithTitle:@"Account retrieval unsuccessful"
                                                                   message:@"Unable to retrieve current account information"
                                                                  delegate:self
                                                         cancelButtonTitle:@"OK"
                                                         otherButtonTitles:nil];

            [errorMessage show];
        }
    }];
}

リクエストをメイン スレッドで実行しようとしましたが、既にメイン スレッドで実行されているようです…getCurrentClientバックグラウンドで実行される内部から呼び出された実際のリクエストだと思います。

- (void)getCurrentClient:(void (^)(BOOL completed, NSDictionary *account))completion
{
    __block BOOL operationSuccessful = NO;
    __block NSDictionary *currentClient = nil;
    NXOAuth2Account *currentAccount = [[[NXOAuth2AccountStore sharedStore] accounts] lastObject];

    [NXOAuth2Request performMethod:@"GET"
                        onResource:[NSURL URLWithString:[NSString stringWithFormat:@"%@/clients/%@", kCatapultHost, currentAccount.userData[@"account_name"]]]
                   usingParameters:nil
                       withAccount:currentAccount
               sendProgressHandler:nil
                   responseHandler:^ (NSURLResponse *response, NSData *responseData, NSError *error) {
                       if (error != nil) {
                           operationSuccessful = NO;
#if DEBUG
                           NSLog(@"ERROR: %@", error);
#endif
                       }
                       else {
                           operationSuccessful = YES;

                           NSError *jsonError;

                           currentClient = [NSJSONSerialization JSONObjectWithData:responseData
                                                                            options:kNilOptions
                                                                              error:&jsonError];

                           if (jsonError != nil) {
                               operationSuccessful = NO;
#if DEBUG
                               NSLog(@"Error: %@", jsonError);
#endif
                           }
                       }

                       completion(operationSuccessful, currentClient);
                   }];
}

それで、私のアプローチ(reloadDataを呼び出す)は良いものですか?リクエストが完了するまでテーブル ビュー コントローラを待機させる方法はありませんか?

4

1 に答える 1

3

いいえ、Table View Controller を待機させることはできません。リロード データの呼び出しは、Web サービスからのコールバックの通常のパターンです。データを表示する前にネットワーク呼び出しが完了するのを待っている場合、できることはあまりありません..ここにいくつかのアイデアがあります...

ロード中に進行状況インジケーターが表示される場合があります。

または、これより前に別のビュー コントローラーがある場合は、データの読み込みをトリガーするボタンを押すことができます。リクエストが完了すると、新しいテーブル ビュー コントローラーがデータの準備が整った状態で画面にプッシュされます。

より高度な方法は、モデル オブジェクトでキー値監視 (KVO) を使用することです。テーブルはモデル オブジェクトをデータ ソースとして使用します。ネットワークから読み込み、モデル オブジェクトに結果を入力します。KVO は、新しいデータが到着したことを静的テーブルに通知することを処理し、それを表示する必要があります (テーブル全体のリロードを行うのではなく)...ただし、最初は空白の状態のままです。

于 2013-04-30T19:33:31.577 に答える