web-dev-qa-db-ja.com

UITableView dequeueReusableCellWithIdentifier Theory

Appleが最初のiPhone用にUITableViewを開発したとき、スクロールするとパフォーマンスに問題がありました。その後、賢いエンジニアの1人が、この原因はオブジェクトの割り当てが原因であることを発見しました代金を払って、彼は細胞を再利用する方法を思いついた。

「オブジェクトの割り当てには、特にユーザーがテーブルビューをスクロールするときなど、割り当てを短期間に繰り返し行う必要がある場合、パフォーマンスコストがかかります。新しいセルを割り当てる代わりにセルを再利用すると、テーブルビューのパフォーマンスが大幅に向上します。」

ソース:iOSリファレンスライブラリ

使用するセルを再利用するには:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

さて、ここで実際に何が起こるのでしょうか。その識別子を持つセルがあり、そのセルを返す場合、TableViewを調べますか?ええ、そうですが、割り当ての代わりに参照を送信し、テーブルビューがあり、すべて同じ識別子を持つ4つのセルがすべて表示されているとしましょう。割り当てることなく、それ自体をどのようにして4つのインスタンスに乗算できますか?

カレンダータイプのコンポーネントを作成していて、すべてのセルが同じ構造を持っているのは、変更内のテキストのみなので、これを知りたいのです。したがって、割り当ての代わりに何らかの方法でセルを再利用できれば、より良いパフォーマンスが得られると思います。

私自身の理論では、4つのセルが割り当てられているとしています(単にそうしているからです)。セルが画面から消えると、TableView再利用キューに入れられます。新しいセルが必要な場合、同じ識別子のセルが利用可能かどうかをキューで調べ、そのセルでprepareForReuseメソッドを呼び出して、キューから自分自身を削除します。

33
Mark

dequeueReusableCellWithIdentifier:は、再利用可能としてマークされている場合にのみcellを返します。これが、ほとんどすべてのcellForRowAtIndexPath:メソッドで次のようなものが表示される理由です



UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

// Do something to cell

return cell;

実際には、tableview(さらに1つまたは2つ以上)の可視部分を満たすのに十分な行が割り当てられます。画面からcells scrollがオフになると、tableから削除され、reuseの準備ができているとマークされます。 「使用可能なセル」のキューが大きくなると、dequeued cellを要求する行が、使用するcellの取得を開始します。この時点で、割り当てる必要はありません。

43
Jerry Jones

deqeueueReusableCellsWithIdentifier:のコードは次のようになります。

(私がページスクロールビューのビュー/ページで同様のことをしている自分のプロジェクトの1つから取られました)

- (UIView*) dequeueReusablePage
{
    UIView* page = [reusablePages_ anyObject];
    if (page != nil) {
        [[page retain] autorelease];
        [reusablePages_ removeObject: page];
    }
    return page;
}

そのため、再利用可能なオブジェクトを含む単純なNSMutableSetが保持されます。

セルが画面からスクロールして見えなくなると、このセットに入れられます。

したがって、空のセットから始めて、実際に表示するデータが他にある場合にのみセットが大きくなり、画面に表示されます。

使用済みのセルは、画面上部からスクロールしてセットに入れられ、画面下部に表示されるセルに割り当てられます。

13
Stefan Arentz

dequeueReusableCellWithIdentifierの目的は、使用するメモリを少なくすることです。 tableViewで100個のセルを使用する場合、毎回100個のセルを作成する必要があります。アプリの機能が低下し、クラッシュが発生する可能性があります。そのため、dequeueReusableCellWithIdentifierは、作成した特定の数のセルを初期化します。セルは、さらに処理するために再度使用します。

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifier];
    }

    ExternalClassTableViewCell *myCell = [[ExternalClassTableViewCell alloc]init];
    myCell.MyCellText.text = [tableData objectAtIndex:indexPath.row];
    myCell.MyCellImage.backgroundColor = [UIColor blueColor];

    return cell;
}
2
Ram Madhavan