16

200 のセクションに約 400 のセルを持つ UITableView がありますが、ユーザーの操作 (スクロール、セルの選択) への応答が少し遅いです。遅くするために何か特別なことをしているとは思いません。セルとヘッダーには、背景画像とテキストのみがあります。他の誰かがこの種の問題を抱えていましたか?それを少し速く実行する方法を知っていますか?

編集:これについて有益なフィードバックが欲しいので、報奨金を提供します。答えが私のコードの問題にあるとは思いません。代わりに、より高速に実行できるように UITableView を再設計する戦略を探しています。私は新しいコードを追加することに完全にオープンであり、皆さんの意見を聞くのを楽しみにしています.

シミュレーターと私のデバイスである iPhone 4 の両方で動きの鈍さが見viewForHeaderInSectionられcellForRowAtIndexPathますUITableViewDelegate。セルとヘッダー ビューを再利用しています。

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger) section
{
    HaikuHeaderView* view= [m_sectionViews objectAtIndex:section];
    NSMutableArray* array= [m_haikuSearch objectAtIndex:section];
    Haiku* haiku= [array objectAtIndex:0];

    [view.poetLabel setText:[haiku nameForDisplay]];

    return view;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

        cell.backgroundView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell gradient2.png"]];

        // (Set up a bunch of label attributes in the cell...)
    }

    NSMutableArray* array= [m_haikuSearch objectAtIndex:indexPath.section];
    Haiku* haiku = [array objectAtIndex:indexPath.row];
    cell.textLabel.text = [haiku.m_lines objectAtIndex:0];

    return cell;
}
4

9 に答える 9

50

セルが実際には単純なもの (背景画像とラベル) であっても、考慮すべき点がいくつかあります。

画像のキャッシング これは明らかなことです。どこでも同じ画像を使用している場合は、一度 UIImage にロードして再利用してください。システムが独自にキャッシュする場合でも、すでにロードされているものを直接使用しても問題はありません。

高速計算 もう 1 つの明らかなことは、高さとコンテンツの計算をできるだけ高速にすることです。同期フェッチ (ネットワーク呼び出し、ディスク読み取りなど) を行わないでください。

画像のアルファチャンネル 描画時にコストがかかるのは透明度です。セルの背景には何もないため、アルファ チャネルなしで画像を保存してください。これにより、多くの処理が節約されます。

透明なラベル バックグラウンド ビューの上のラベルについても同じことが言えます。残念ながらラベルを不透明にすると、セルの外観が損なわれる可能性がありますが、画像によって異なります。

カスタム セル一般に、サブビュー階層を構築するよりも、自分 でサブクラス化UITableViewCellして実装する方が高速です。drawRect:イメージを、すべてのインスタンスが使用するクラス変数にすることができます。そのdrawRect:上に画像とテキストを描画します。

合成のチェック シミュレーターには、透明度のためにレンダリング負荷が高い部分を強調表示するツールがあります (緑は問題なく、赤はアルファブレンディングです)。これは、デバッグ メニューの [カラー ブレンド レイヤー] にあります。

于 2011-06-23T09:42:39.293 に答える
9

コードの高速化を検討している場合にできる最善のことは、コードをプロファイリングすることです。これには2つの理由があります。

  1. 固定高さのセルの使用やセルの再利用など、一般的にテーブルのパフォーマンスを向上させるいくつかのことについて読むことができ、おそらくそれらのことを実装するのに役立ちます(すでにそれを行っているように見えます)。ただし、コードの高速化に関しては、アプリがほとんどの時間をどこで費やしているかを知る必要があります。非常に長い時間がかかるメソッドや、比較的高速であるが予想よりも頻繁に呼び出されるメソッドがいくつかある可能性があります。

  2. 物事をスピードアップするために行った変更が、測定する数値がない限り、本当に違いを生むかどうかを知ることは不可能です。コードが1つのルーチンでその時間の80%を費やしていたことを示すことができ、それを35%に削減した場合、進歩していることがわかります。

それで、機器を分解して測定を開始します。可能であれば、スピードアップしたいさまざまなアクティビティのそれぞれを実行している間に測定することをお勧めします...スクロールしながら1回のプロファイリングセッションを実行し、1回は一定期間内にできるだけ多くの異なるセルを選択します、など。後で比較できるように、結果を保存することを忘れないでください。

于 2011-06-21T04:51:58.197 に答える
5

これらの点に注意してください..

  1. セルを再利用していますか..これは良い習慣です..
  2. cellForRowAtIndexPath コールバック、または CellForRowAtIndexPath から呼び出される関数で高価な計算を行っていないことを確認してください。
  3. あなたは背景画像があると言いました。セルを再利用しなければならないもう 1 つの理由。

セルの再利用に関するいくつかの良い情報はここにあります..

編集:このページは非常に遅く見つかりました..

このSO質問スレッドはあなたを助けるかもしれません...特に受け入れられた答え...

于 2011-05-30T04:22:18.400 に答える
3
  1. 背景に共有イメージ インスタンスを使用します (新しいセルが作成されるたびに 1 つを割り当て/初期化/解放します)。テーブル ビューが大きい場合、これはメモリ内のバックグラウンド X セルが必要以上に多くのメモリを消費することを意味します。


    cell.backgroundView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell gradient2.png"]];
    単に使用する代わりに:
    cell.backgroundView= [SomeHelperClass sharedBackgroundUIImageResource];

  2. それでも問題が解決しない場合は、ラベルやその他のサブビューの代わりに CG を使用してください (ここでスクリーンショットが役立ちます.. 何について話しているかを理解するのに役立ちます)。

于 2011-06-22T05:50:56.567 に答える
2

テーブル ビューのデリゲートは次を実装していますか。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

その場合は、代わりに UITableViewCell の rowHeight プロパティを設定することを検討してください。

于 2011-05-30T04:29:36.313 に答える
1

2つの提案:1つは-initWithStyle:reuseIdentifier:、-initWithFrame:の代わりにテーブルビューセルに使用することです。もう1つは、cell.backgroundViewをグラデーションのある画像に設定することをコメントアウトし、それが原因かどうかを確認することです。テーブルビューでパフォーマンスが低下するたびに、画像が原因でした。

于 2011-06-21T04:48:18.880 に答える
1

多くのサブビューを使用していますか?

その場合、大量のラベルや画像を追加する代わりに、CoreGraphics を使用してそれらを描画することをお勧めします。

これを行うには、UITableViewCell をサブクラス化し、-(void)drawRect:(CGRect)rectメソッドを実装する必要があります。

于 2011-06-21T04:33:46.693 に答える
0

これはここでは少し話題から外れています (すべてのセルに対して背景画像が 1 つしかないため)。

私のアプリは、各セルに異なる画像を表示します。UITableView に約 5 個のセルを追加すると、テーブルの速度が大幅に低下します。ビューコントローラーを開くたびに、すべての画像を処理するのに約1〜2秒かかります。

if let image = UIImage(contentsOfFile: photoFile){
    // just set it and let system fit it
    //cell.imageView!.image = image

    // 1 - Calculate sized
    let DEFAULT_THUMBNAIL_WIDTH: CGFloat  = (cellHeight / 4) * 5;
    let DEFAULT_THUMBNAIL_HEIGHT: CGFloat = cellHeight;

    let aspectRatio: CGFloat = image.size.width / image.size.height
    var willBeHeight = DEFAULT_THUMBNAIL_HEIGHT
    var willBeWidth  = DEFAULT_THUMBNAIL_HEIGHT * aspectRatio

    if(willBeWidth > DEFAULT_THUMBNAIL_WIDTH){
        willBeWidth = DEFAULT_THUMBNAIL_WIDTH
        willBeHeight = willBeWidth / aspectRatio
    }

    let eps:CGFloat = 0.000001
    assert((willBeHeight - eps) <= DEFAULT_THUMBNAIL_HEIGHT);
    assert((willBeWidth - eps) <= DEFAULT_THUMBNAIL_WIDTH);

    // 2 - Create context
    var size:CGSize = CGSize(
        width: DEFAULT_THUMBNAIL_WIDTH,
        height: DEFAULT_THUMBNAIL_HEIGHT)
    UIGraphicsBeginImageContext(size)

    // one-to-one rect
    //var imageRect: CGRect = CGRectMake(0.0, 0.0, size.width, size.height)
    var imageRect: CGRect = CGRectMake(0.0, 0.0, willBeWidth, willBeHeight)

    // 3 - Draw image
    image.drawInRect(imageRect)
    var imageResult: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    cell.imageView!.image = imageResult

    UIGraphicsEndImageContext()
}else{
    DDLogError("Can not draw photo: \(photoFile)")
}

そのため、すべての画像に対して小さな THUMBNAILS を生成することになりました。

于 2015-06-27T13:44:03.327 に答える
-1

セルを再利用します。オブジェクトの割り当てにはパフォーマンス コストがかかります。たとえば、ユーザーがテーブル ビューをスクロールするときなど、割り当てが短期間に繰り返し発生する必要がある場合は特にそうです。新しいセルを割り当てる代わりにセルを再利用すると、テーブル ビューのパフォーマンスが大幅に向上します。コンテンツの再レイアウトを回避します。カスタム サブビューでセルを再利用する場合は、テーブル ビューがセルを要求するたびにそれらのサブビューをレイアウトしないでください。セルが作成されるときに、サブビューを 1 回レイアウトします。不透明なサブビューを使用します。テーブル ビュー セルをカスタマイズするときは、セルのサブビューを透明ではなく不透明にします。

于 2011-07-22T09:34:15.040 に答える