14

解決策: SDWebImage を使用します: https://github.com/rs/SDWebImage

スクロール中に非常に遅くなる UITableView があります。使用している画像が画面に戻ってくるときにラグが発生することを発見しました。

カスタム UITableViewCell を使用しています。これも遅れている理由でしょうか?

私のカスタム UITableViewCell:

ここに画像の説明を入力

私のコード:

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

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.row,indexPath.section];


tableViewCellActiviteiten *cell = (tableViewCellActiviteiten *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"tableViewCellActiviteiten" owner:self options:nil];
    cell = (tableViewCellActiviteiten *)[nib objectAtIndex:0];
}


cell.thetitle.text = [self.alletitels objectAtIndex:indexPath.row];
cell.thesubtitle.text = [self.allesubtitels objectAtIndex:indexPath.row];

NSString * imagePath = [self.alleimages objectAtIndex:indexPath.row];

NSURL * imageURL = [NSURL URLWithString:imagePath];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];

cell.image.image = image;

return cell;

}

配列の内容:

self.alletitels次の文字列が含まれています: "Activity Title"

self.allesubtitels「Activity Subtitle」という文字列が含まれています

self.alleimages次の URL が含まれています: " http://m2.myhappygames.com//files/pics/0/Paranormal_Shark_Activity_3.jpg "

遅延スクロールの原因は何か、誰にもアドバイスできますか?

4

7 に答える 7

9

tableView: cellForRowAtIndexPath:問題は、メソッドが呼び出されるたびにコードが画像を生成することです。これは、セルが画面に表示されるたびに呼び出されるため、非常に高速にスクロールすると、このメソッドは同期的に多くの画像を割り当て始め、スクロールが遅くなります。

迅速な解決策として、View Controller に NSCache を実装し、そこに画像を保存します。

UIImage *image = [_imageCache objectForKey:@indexPath.row];
if (image == nil) {
    NSString * imagePath = [self.alleimages objectAtIndex:indexPath.row];
    NSURL * imageURL = [NSURL URLWithString:imagePath];
    NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
    image = [UIImage imageWithData:imageData];
    [_imageCache setObject:image forKey:@indexPath.row];
}

cell.image.image = image;

_imageCahce は、実装可能なビュー コントローラーのインスタンス変数です。

これが役に立てば幸いです、乾杯!

于 2013-09-18T13:02:24.647 に答える
4

セルが作成されている間、画像をダウンロードするために同期ネットワーク呼び出しを行っています。これらの呼び出しは、セルのイメージがダウンロードされるまでメイン スレッドをブロックします。遅延時間は、ネットワークの品質によって異なります。

これに対する解決策は、「遅延読み込み」と呼ばれる手法を使用することです。この手法では、イメージの読み込みが別のスレッドで行われるため、メイン スレッドのブロックが解除されます。イメージがダウンロードされ、正しいコンテナに適用されますUIImageView。以下は、テーブル ビューで画像を遅延読み込みするためのApple のサンプル コードです。

SDWebImageも使用できます。これにより、画像のキャッシュも行われます。

#import <SDWebImage/UIImageView+WebCache.h>

...

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];

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

    // Here we use the new provided setImageWithURL: method to load the web image
    [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
                   placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

    return cell;
}

それが役立つことを願っています!

于 2013-09-18T13:07:49.653 に答える
2

各画像に対して同期ネットワーク呼び出しを行っているため、アプリで遅延が発生しています。AsyncImageViewを試す と、Web から画像が Asynchronously にダウンロードされます。また、アプリからラグを取り除くことができます。:-)

于 2013-09-24T14:03:24.563 に答える
2

同様の問題があり、プロファイラーで調べたので、いくつかのヒントを次に示します。

1) 間違った再利用可能な識別子を使用しています。常に同じ識別子を使用する必要があります。

これの代わりに:

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.row,indexPath.section];

これを使って:

NSString *CellIdentifier = @"MyIdentifier";

詳細については、次を参照してください: UItableViewCell reuseIdentifier の使用方法

2) loadNibNamed メソッドは非常に遅いです (さらに、セルごとに毎回ロードしています)。ペン先を取り除き、UITableViewCell のこのメソッドを上書きして、コードから UI 要素を配置する必要があります。

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;

3)楽器を使う

于 2013-09-23T13:55:37.407 に答える
2

スクロールしているのと同じ UI スレッドに画像を読み込もうとしています。それらをバックグラウンドでキャッシュにロードし、表示する準備ができたらキャッシュから取得する必要があります。

于 2013-09-18T12:57:11.790 に答える