4

[セルを返す]の前の最後の行を確認してください。画像が読み込まれた後、スクロール速度が低下しています。スクロールが動かなくなったようです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
    }

    int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    NSString *itemDescription=[[stories objectAtIndex: storyIndex]
                                                 objectForKey:@"title"];

    CGRect aframe = CGRectMake(80, 30, 250, 40); 
    textLabel = [[UILabel alloc] initWithFrame:aframe];
        textLabel.font = [UIFont boldSystemFontOfSize:14];
    textLabel.numberOfLines=0;
    textLabel.textColor = [UIColor darkTextColor];
    textLabel.backgroundColor = [UIColor whiteColor];
    [cell.contentView addSubview:textLabel];
    textLabel.text=itemDescription;

    CGRect frame = CGRectMake(0, 0, 70,80);
    UIImageView *TopImageView = [[UIImageView alloc] init];
    [cell.contentView addSubview:TopImageView];
    TopImageView.frame=frame;

    m_strImage = [m_imglinkArray objectAtIndex:storyIndex]; 

    TopImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:m_strImage]]];
    TopImageView.image=TopImage;

    return cell;
}

スクロールの速度を上げるのを手伝ってくれませんか。

よろしく

アルン

4

4 に答える 4

3

ここで2つの問題があると思います。1つは、画像の読み込みをマルチスレッド化しないという問題であり、2つ目は、UITableViewCellの使用方法です。

iPhoneは、セルが画面に表示されるたびにcellForRowAtIndexPathを呼び出します。下にスクロールすると、もう一度上にスクロールすると、上記のすべてがアンロードおよびリロードされます。すでに述べたように、これはマルチスレッドパターンで解決できます-markj.netに投稿されたリンク、またはNSThreadを使用します。NSThreadの利点は、問題を処理したり、画像データだけでなくロードしたりするための柔軟性が高いことです。(私は両方を使用します)

これを効率的に行うには、カスタムUITableViewCellが必要です。これは、View Controllerではなくテーブルセルにコンテンツの責任を負わせることができ、セルの書式設定とコンテンツを効率的に操作できるため、関係なく使用するのに適しています。UITableCellViewに関するすばらしい投稿へのリンクは次のとおりです。http: //blog.atrexis.com/index.cfm/2009/1/6/iPhone--Customize-the-UITableCellView

UITableViewCellを実装するときは、カスタムinitWithFrameに配置できない場合にのみ、すべてのaddSubViewおよび書式設定呼び出しを「if(cell == nil)」ブロックに配置するように最善を尽くしてください。iPhoneは、追加したすべてのサブビューをスタックしていることがわかります。古いビューはクリアされていません。すべての背景色を「UIColorclearColor」に設定し、ヒット間でテキストを変更することで、これが機能していることを確認できます。テキストのスタックが互いに重なり合って表示されます。塗りつぶされた背景がすべての「古い」サブビューを描画するため、これは通常は表示されません。

これら2つの方法を組み合わせる前に、「モデル」の実装を検討してください。ビューとコントローラーがありますが、すべてのデータはモデルに含まれている必要があります。すべての画像のURL、コンテンツなどは、NSMutableArrayのようなもの、独自のカスタムオブジェクト、またはSQLite経由である必要があります。モデルを作成したら、画像のキャッシュを実装できます。キャッシュを使用すると、アプリケーションのロード間ですべての画像が保持されるため、バッテリー、帯域幅、および時間が節約されます。

1.すべてのデータをある種のモデル(NSMutableArray、SQLLiteなど)に配置します2.独自のカスタムUITableViewCellを実装します3. cellForRowAtIndexPath 4のアクティブブロック内にaddSubView、init、またはalloc呼び出しが0個あることを確認します。委任の例またはNSThreadを使用して、バックグラウンドですべての画像をロードします。5.ローカル画像キャッシュを追加します。

画像のキャッシュに関するAppleフォーラムについて、およびAppleフォーラムにいくつかの良い例があります。

于 2009-05-05T12:15:49.623 に答える
2

nessenceにはたくさんの良い情報があります。さらにいくつかの考え:

あなたはここで狂ったように漏れています。作成するすべてのセルで、UIImageView と UIImage の 2 つの UILabels がリークします。

前に述べたように、これらをリークしているだけでなく、addSubview: を使用して一方を他方の上に貼り付けているため、それらがビューに蓄積されています。

セルの描画中にネットワークにアクセスすると、非常に遅くなり、UI がブロックされます。これらの URL がローカルの場合は、UIImage の +imageWithContentsOfFile を使用できます。そうでない場合は、これをバックグラウンドでロードする必要があります。

ここにスレッドを立てる必要はないと思います。NSURLConnection は、スレッドのオーバーヘッドを発生させずにバックグラウンドでデータをロードするための優れた方法です。

Story 用のモデル クラスが必要であるという本質は完全に正しいです。

再利用可能なセル構成に対する基本的なアプローチは正しくありません。再利用可能なセルを取得してからサブビューを追加することはありません。セルを作成するには、すべてのサブビューを if() ブロックに追加する必要があります。次に、各パスで、物事の値を変更するだけです。デモ用に、以下のコードの一部を書き直しました。セルの描画中にネットワークに到達しているため、これはまだ正しいコードではありません。これは、(カスタム セルではなく) サブビュー セルに含めるには要素が多すぎる可能性がありますが、正しい考えに近いものです。これがコンパイルされるかどうかさえわかりません。ここに入力しただけです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];

    if (cell == nil) {
        // Here we do all our cell creation
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];

        // Make the label
        CGRect aframe = CGRectMake(80, 30, 250, 40);
        UILabel *textLabel = [[[UILabel alloc] initWithFrame:aframe] autorelease]; // Note the -autorelease so we don't leak

        textLabel.font = [UIFont boldSystemFontOfSize:14];
        textLabel.numberOfLines=0;
        textLabel.textColor = [UIColor darkTextColor];
        textLabel.backgroundColor = [UIColor whiteColor];
        textLabel.tag = DescriptionTag; // A tag so we can find it later (you'll need a constant for this)
        [cell.contentView addSubview:textLabel];

        // And the second label
        aframe = CGRectMake(80, 30, 250, 40);
        textLabel = [[[UILabel alloc] initWithFrame:aframe] autorelease];
        textLabel.font = [UIFont boldSystemFontOfSize:14];
        textLabel.numberOfLines=0;
        textLabel.textColor = [UIColor darkTextColor];
        textLabel.backgroundColor = [UIColor whiteColor];
        textLabel.tag = TitleTag;
        [cell.contentView addSubview:textLabel];

        // The image view
        CGRect frame = CGRectMake(0, 0, 70,80);
        UIImageView *topImageView = [[[UIImageView alloc] init] autorelease];
        topImageView.frame = frame;
        topImageView.tag = TopImageTag;
        [cell.contentView addSubview:topImageView];
    }

    // all the above was cell creation; we do that as seldom as possible.
    // Now we do cell configuration. We want this to be fast.

    UILabel *descriptionLabel = (UILabel*)[cell.contentView viewWithTag:DescriptionTag];
    descriptionLabel.text = itemDescription;

    UILabel *titleLabel = (UILabel*)[cell.contentView viewWithTag:TitleTag];
    titleLabel.text =[[stories objectAtIndex:indexPath.row] objectForKey:@"title"];

    NSString *imageURLString = [m_imglinkArray objectAtIndex:storyIndex]; // You should have a model class called Story, not two arrays.
    UIImage *image = [[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURLString]]] autorelease]; // This is still way too slow if it's a remote URL 
    UIImageView *imageView = (UIImageView*)[cell.contentView viewWithTag:TopImageTag];
    imageView.image = image;    

    return cell;
}

TableViewSuitePractical Memory Management、およびCocoa のコーディング ガイドライン の学習に時間を費やすことをお勧めします。Cocoa の基本を少し勉強することも役に立ちます。ここでのコーディング スタイルは、確かな基盤がない可能性があることを示しているからです。これは Mac の本ですが、やはりCocoa Programming for Mac OS X をお勧めします。これを使用して iPhone を学習することに興味がある場合は、役立つシラバスをまとめました。まだレビューしていませんが、スタンフォード大学のオンラインCS193P コースは有望に見えます。

于 2009-05-05T14:06:39.747 に答える
0

テーブルビューが行のセルを取得するように要求するたびに、URLからロードしているようです。これはメインアプリケーションスレッド(ユーザーインターフェイススレッド)で発生しており、ユーザーインターフェイスをブロックして、応答しなくなります。

特に、このURLがインターネットからロードするリソースである場合、この一時停止は大きくなります。

画像をバックグラウンドスレッドにロードし、ネットワークから取得されるまでプレースホルダー画像を表示することをお勧めします。

次のURLで提供されているソリューションを試すことができます...

http://www.markj.net/iphone-asynchronous-table-image/

于 2009-05-05T07:05:40.837 に答える