2011-07-26 3 views
7

UITableViewControllerのサービスのデータをviewDidLoadメソッドでロードしています。問題は、データの取得と解析に時間がかかり、ビューを作成するのに時間がかかることです。 このデータをロードする最適な場所はどこですか?私は、ビューが作成された後にデータをロードするためのどこかにフックがあると仮定します。これを行うことで、私は最終的なビューでUIActivityIndicatorViewを使用することができます。 ありがとうUITableViewControllerでデータをロードするタイミングは?

答えて

1

あなたが尋ねようとしているのは、WebサービスからのデータをUITableViewに表示するためのワークフローです。ここで

は、私がお勧めするものです:

  • あなたviewDidLoadは、あなたのJSONファイルのNSURLRequestになります。また、 は、現在のビューにローディングビューを追加します(UIViewには、 ブラックbg(0.5アルファ)、ラベルとUIActivityIndi​​catorを使用)。この メソッドでは、loadedというBOOL ivar( ヘッダーに追加する必要があります)をNOに設定します。

  • NSURLRequestのデータは、可変データファイル に変換されます。

  • NSURLRequestが終了したら、そのデータを文字列 に変換し、JSONを何らかの並べ替えの配列(または が必要な場合は辞書)に解析します。同じ方法でローディングビューを削除し、 ブール値loadedをYESに変更します。 [self.tableView reloadData];ここ

はマジックが起こるだ...あなたは新しいビューを開いて、メッセージの持つUIActivityIndi​​catorを表示することができます

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    if (loaded) return [myArrayOfJSONObjects count]; 
    return 0; // Will only return 0 if the data is not downloaded 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSUInteger row = [indexPath row]; 

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    // Configure the cell... 
    if (loaded) { 
     cell.textLabel.text = [myArrayOfParsedJSONObjects objectAtIndex:row]; 
     //Anything else you want to set 
    } 
    else { 
     //Do nothing :) - you shouldn't reach this else anyway because your numberOfRows method should stop it 
    } 
} 
+0

正確ではありません。これは私がすでにしていることです。私はviewDidLoadのデータを読み込んで、cellForRowAtIndexPathにテーブルを移入します。それは動作しますが、私が言ったことは、この場合、JSONサービスが返信するのに10秒かかる場合、ユーザーがそれを選択してから10秒後に表示されることです。私の場合、ユーザーが行をクリックすると、別のテーブルビューからビューが読み込まれます。 –

+0

これまでにロードできる場所があるのですか? –

+0

もちろんどこでもロードすることができますが、私は何をしたいのですか?1 /ビューを表示する(潜在的に空のテーブル)2 /自動的にリモートサービスからデータをロードする2 '/ロード中にいくつかの待機メッセージを表示する –

0

あなたのテーブルビューメソッドに:あなたは、それがデータだ をリロードするのtableViewを伝えますユーザーのために、彼のために新鮮なデータを読み込んでいます。

インターフェイスは責任を負い、ユーザーは実際に何かやアプリがハングしていないかを見ているので、これが最良の選択です。

- (void) viewDidLoad 
{ 
    dataLoaded = NO; 

    [self initSpinner]; 
    [self launchLoadData]; 
... 
} 

-(void)launchLoadData { 
    NSLog(@"Launching thread"); 
    [NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil]; 
} 

- (void) loadData { 
    dataLoaded = NO; 
    NSLog(@" thread launched"); 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [self loadDataFromURL:nil]; 
    dataLoaded = YES; 
    [self.tableView reloadData]; 
    [pool release]; 
} 

- (void)loadDataFromURL:(NSString*)url { 
    // start the spinner to show that loading may be time consuming... 
    [NSThread detachNewThreadSelector: @selector(spinBegin) toTarget:self withObject:nil]; 
    JSONLoader *loader = [[JSONLoader alloc] init]; 
    self.accounts = [loader getAccountsFromURL:@"http://foo/bar/repository.json"]; 
    [loader release]; 
    //[NSThread sleepForTimeInterval:3]; 
    [NSThread detachNewThreadSelector: @selector(spinEnd) toTarget:self withObject:nil]; 
} 

とテーブル内のデータを表示したりしないようにフラグを使用します。すべてをブロックせずにデータを取得するためのviewDidLoadでスレッドを起動します。

+0

新しいこの場合、私はこのローダーを停止します。[tableview reloadData] –

5

は最後に、ここでコメントに基づいてソリューションです。スレッドから呼び出されると、tableView reloadDataは残りの処理を行います。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    if (dataLoaded) return [self.accounts count]; 
    return 0; 
} 
関連する問題