2012-05-15 65 views
6

私はUITableViewを持っています。 tableView:cellForRow:atIndexPath:のメソッド(データがセルに読み込まれるとき)では、何らかの遅延読み込みを実装しました。 rowDataNSDictionaryにキーのオブジェクトがない場合(キー==行番号)、プログラムはバックグラウンドでrequestDataForRow:メソッドを起動します。セル内のデータは、セルが表示された後に少しポピュレートされます。私のテーブルは2000行を持っており、指標10を持つセルからユーザーがスクロールは非常に迅速にインデックス2000でセルにいる場合このコードは動作しますが、すべてが、OKですUITableView遅延ロード最適化

static int requestCounter=0; 

-(void)requestDataForRow:(NSNumber *)rowIndex 
{ 
    requestCounter++; 
    //NSLog(@"requestDataForRow: %i", [rowIndex intValue]); 
    PipeListHeavyCellData *cellData=[Database pipeListHeavyCellDataWithJobID:self.jobID andDatabaseIndex:rowIndex]; 
    [rowData setObject:cellData forKey:[NSString stringWithFormat:@"%i", [rowIndex intValue]]]; 
    requestCounter--; 

    NSLog(@"cellData.number: %@", cellData.number); 

    if (requestCounter==0) 
    { 
     //NSLog(@"reloading pipe table view..."); 
     [self.pipeTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 
    }; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *MyIdentifier = @"pipeCellIdentifier"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 
    [[NSBundle mainBundle] loadNibNamed:@"PipesForJobCell" owner:self options:nil]; 
    cell = pipeCell; 
    self.pipeCell = nil; 


    PipeListHeavyCellData *cellData=[[PipeListHeavyCellData alloc] init]; 

    if ([rowData objectForKey:[NSString stringWithFormat:@"%i", indexPath.row]]==nil) 
    { 
     //NSLog(@"  nil data for row: %i", indexPath.row); 
     [self performSelectorInBackground:@selector(requestDataForRow:) withObject:[NSNumber numberWithInt:indexPath.row]]; 
    } 
    else 
    { 
     //NSLog(@"  has data for row: %i", indexPath.row); 
     PipeListHeavyCellData *heavyData=[[PipeListHeavyCellData alloc] init]; 
     heavyData=(PipeListHeavyCellData *)[rowData objectForKey:[NSString stringWithFormat:@"%i", indexPath.row]]; 
     cellData._id=[heavyData._id copy]; 
     cellData.number=[heavyData.number copy]; 
     cellData.status=[heavyData.status copy]; 
}; 

しかし:ここ のコードです。すべてのデータ要求が完了するまで(11,12,13、...、2000行)、ユーザーがテーブルビューをスクロールしている間に行が表示され、メソッドrequestDataForRowが呼び出されるまで、長い時間待たなければなりません。

これらのものを最適化するにはどうすればよいですか?

+1

ここでは、いくつかの非常に良いソリューション(コード付き)で同じ問題が発生した場合の素晴らしい質問があります:http://stackoverflow.com/q/7567827/937822 – lnafziger

答えて

4

私は似たようなことをしなければなりませんでした。最近追加されたアイテムを最初に処理するキューを作成する必要があります。

たとえば、ユーザーがテーブルを開き、10個の要求がキューに入れられます。最初のオブジェクトをデキューし、最初の行のデータの取得を開始します。ただし、ユーザーは31〜40行目までスクロールダウンします。キューの最初の10の前にそれらの行を挿入する必要があります。これは、キューの優先順位が高くなったためです。鍵は、即座に10の要求をすぐに開始するのではなく、順番に処理することです。こうすると、ユーザーがスクロールすると、最後に行われた要求である1つの要求だけが「廃棄」されます。

これを実際に実装する簡単な方法は、[tableView indexPathsForVisibleRows]を使用することです。

+0

ありがとう、私の考えは似ています。 – user1385666