7

tableView:cellForRowAtIndexPath:nib ファイルからカスタム テーブル セルを読み込んでいます。これは、非常に遅いことを除けば、私の目的には最適です。

これで、長期的には、セル全体をコードで作成し、単一のビューを使用するなどの方法が正しいことがわかりました。しかし、これは試作品であり、そこまで力を入れたくありません。

UIViewController今のところ、ペン先をサブクラスで 1 回だけ読んで、それtableView:cellForRowAtIndexPath:をコピーしておけばよかったと思います。ここでの私の仮定は、ペン先を読むよりもコピーの方が速いということです。

これは、私が呼び出すペン先をロードするために使用するものですviewDidLoad:(およびretainその後)

-(id)loadFromNamed:(NSString*)name {
    NSArray *objectsInNib = [[NSBundle mainBundle] loadNibNamed:name
                                                          owner:self
                                                        options:nil];
    assert( objectsInNib.count == 1 );
    return [objectsInNib objectAtIndex:0];
}

これまでのところ、すべて順調です。しかし問題は、これを何度もコピーするにはどうすればよいかということです。それは可能ですか?

試し[_cachedObject copy]てみましたが、どちらのコピー プロトコルもサポートして[_cachedObject mutableCopy]UITableViewCellません。

必要に応じて、ペン先を完全に取り外す準備が整うまで速度を無視するように指示できますが、ここにぶら下がっている果物がある場合は、もう少し速くしたいと思います.

何か案は?

4

5 に答える 5

8

テーブルセルのコーピングは、セルを1回作成して(nibから、またはプログラムで、または他のnibから自動的にロードして、IBのアウトレットとしてリンクする)、クローンを作成するか、デキューすることができるデキューメカニズムと一緒に使用できると思います。必要に応じて。

UITableViewCellはNSCopyingプロトコルに準拠していませんが、キー付きアーカイブ/アーカイブ解除メカニズムをサポートしているため、クローン作成に使用できます。

「 ObjectiveCでUIButtonを複製する方法は? 」という回答に基づくと 、データソースデリゲートメソッドは次のようになります。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellID = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];

    if (!cell) {
        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
        cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
    }

    // ... config ...

    return cell;
}

私の場合、self.tableViewCellは、ビューのnibファイルから一度ロードされたセルです。

クローンを作成するための「アーカイブ+アーカイブ解除」または-loadNibNamed:owner:options:の場合にフレームワークが実行する「アーカイブ+アーカイブ解除」のテストは行っていません。このメソッドは、利便性を考慮してのみ使用しましたが、メモリ操作とファイル操作の方が速くなる可能性があります。

編集:それは最初に思ったほど簡単ではないようです。UIImageはNSCodingに準拠していないため、UIImageViewsが構成されているセルは、追加のコードなしでコピーすることはできません。うん、画像全体をコピーすることは間違いなく良い習慣ではありません、これを指摘してくれたAppleに乾杯。

于 2011-03-17T12:00:17.693 に答える
6

テーブル ビューに組み込まれているセルの複製を使用します。Apple は、大量のテーブル セルの生成が遅いことを知っていました。このメソッドのドキュメントを確認してください。

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

セルを一度作成すると、新しいセルが要求されたら、そのメソッドを使用して既存のセルを複製します。次に、新しいセルについて変更する必要があるものを変更し、セル オブジェクトを返します。

また、このメソッドを使用して正しい方法を示す、Apple が提供するテーブル ビュー関連のサンプル コードも確認してください。セルがペン先からロードされたという事実は、まったく問題になりません。


マイナーな説明: 上記の方法で細胞をクローンするとは思いません。代わりに、画面からスクロールされたセル オブジェクトを取得し、それらを新しい場所に移動するだけです。つまり、文字通りセルを再利用しています。そのため、カスタム テーブル ビューが、初期化以外で必要なすべての新しい値に設定できることを確認してください。

于 2009-02-20T21:11:32.293 に答える
4

このソリューションは自慢ではありませんが、可能な最大数の IB バインディングで動作します。

インターフェイス (AlbumTableViewCell は、AlbumViewController の XIB ファイルでインスタンスが定義されている UITableViewCell のサブクラスです):

@interface AlbumsViewController : UITableViewController {
    IBOutlet AlbumTableViewCell *tableViewCellTrack;
}

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack;

実装 (アンアーカイブ / アーカイブでコピーを作成 / テーブル ビュー セルのクローンを作成):

@implementation AlbumsViewController

@synthesize tableViewCellTrack;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AlbumTableViewCell *cell = (AlbumTableViewCell *)[tableView dequeueReusableCellWithIdentifier: @"AlbumCell"];

    if (cell == nil) {
        AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease];
        [[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil];

        cell = albumsViewController.tableViewCellTrack;
    }

    cell.labelTitle.text = ...;
    cell.labelArtist.text = ...;

    return cell;
}
于 2009-12-08T09:06:04.163 に答える
3

ええと、そこにあるすべてのチュートリアルでこの手順が指定されていない理由がわかりません。

Nib から独自のカスタム UITableViewCell を使用する場合、dequeueReusableCellWithIdentifier を呼び出すだけでは不十分です。テーブル ビュー セル タブ セクションで、IB に「識別子」を指定する必要があります。

次に、IB に入力した識別子が dequeueReusableCellWithIdentifier に使用する識別子と同じであることを確認します。

于 2009-06-17T04:10:23.230 に答える
1

Swiftではこちら

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell : UITableViewCell?
    let cellId = String(format: "Cell%d", indexPath.row)
    cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?

    if cell == nil {
        let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
        cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
    }

    // do some stuff

    return cell!
}
于 2015-10-24T02:00:45.860 に答える