0

reuseCellIdentifier を使用し、画像 (UIImageView+AFNetworking.h を使用して非同期にダウンロード) を含む UITableView があります。しばらくスクロールした後やテーブルが長くなると、予想どおり動作が遅くなります。また、インターネットからダウンロードした各セルのデータを に保存するNSMutableArray *_collectionので、セルが表示されるたびに再ダウンロードし続けることはありません。

私の問題は、次の方法を使用してテーブルを完全に更新した後でも、スクロールが非常に遅いことです。再びスムーズにロードする唯一の方法は、アプリを終了して再度開くことです。リロード後もスクロールが遅い理由がわかりません... ARCを使用していて、リークのプロファイルを作成しましたが、テーブルをリロードしても何も表示されません..

-(void)refreshTable:(id)sender{
  [_collection removeAllObjects];
  _collection = nil;

  AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:_baseURL]];
  [httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
  NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:_path parameters:nil];
  AFJSONRequestOperation *operation = [AFJSONRequestOperation ...etc...

さらに一歩進んで、次のように更新時にテーブルビューを削除しようとしましたが、どちらも役に立ちません...

-(void)refreshTable:(id)sender{
  [_tableView removeFromSuperView];
  _tableView = nil;
  _tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
  [_tableView setDelegate:self];
  [_tableView setDataSource:self];
  [_tableView setRowHeight:kRowHeight];
  [_tableView setBackgroundColor:[UIColor clearColor]];
  [_tableView setSeparatorColor:[UIColor clearColor]];
  [_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
  [self.view addSubview:_tableView];

  [_collection removeAllObjects];
  _collection = nil;

  AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:_baseURL]];
  [httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
  NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:_path parameters:nil];
  AFJSONRequestOperation *operation = [AFJSONRequestOperation ...etc...

テーブルを更新した後もスクロールが遅い理由は何ですか? ありがとう!

編集

- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = (CustomCell*)[theTableView dequeueReusableCellWithIdentifier:kCustomCellId];
    if (cell == nil)
    {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = (CustomCell*)[topLevelObjects objectAtIndex:0];
    }

    [self populate:cell atIndexPath:indexPath];
    [self loadImageForCell:cell];
    return cell;
}

- (void) populate:(UITableViewCell*)customCell atIndexPath:(NSIndexPath*)indexPath
{
    CustomCell *cell = (CustomCell*)customCell;

    if (indexPath.row % 2) {
        [cell.background setImage:[UIImage imageNamed:@"CellBgYellow"]];
    } else {
        [cell.background setImage:[UIImage imageNamed:@"CellBgOrange"]];
    }

    DataObject* thisDataObject = [_collection objectAtIndex:indexPath.row];
    cell.dataObject = thisDataObject;
    cell.titleLabel.text = [thisDataObject objectForKey:kCellTitle];
    cell.timestampLabel.text = [thisDataObject objectForKey:kCellTimestamp];
}

- (void) loadImageForCell:(CustomCell*)cell
{
    [cell.profilePic setImage:nil];
    NSString* profilePicURL = [cell.dataObject objectForKey:kCellProfilePicURL];    
    NSString* URL = [NSString stringWithFormat:@"%@%@", kBaseURL, profilePicURL];
    NSMutableURLRequest *profilePicRequest = [NSMutableURLRequest requestWithURL:[[NSURL alloc] initWithString:URL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
    [profilePicRequest setHTTPShouldHandleCookies:NO];    
    [cell.profilePic setImageWithURLRequest:profilePicRequest
                           placeholderImage:nil
                                    success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
                                    }
                                    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
                                        NSLog(@"loadimageforcell error (%d): %@",error.code,error.localizedDescription);
                                    }];

    [cell.painting setImage:nil];
    NSString* paintingURL = [cell.dataObject objectForKey:kCellPaintingURL];
    URL = [NSString stringWithFormat:@"%@%@", kBaseURL, paintingURL];
    NSMutableURLRequest *paintingRequest = [NSMutableURLRequest requestWithURL:[[NSURL alloc] initWithString:URL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
    [paintingRequest setHTTPShouldHandleCookies:NO];
    [cell.spinner startAnimating];
    [cell.painting setImageWithURLRequest:paintingRequest
                           placeholderImage:nil
                                    success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
                                        [cell.spinner stopAnimating];
                                        [cell.spinner removeFromSuperview];
                                    }
                                    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
                                        NSLog(@"loadimageforcell error (%d): %@",error.code,error.localizedDescription);
                                        [cell.spinner stopAnimating];
                                        [cell.spinner removeFromSuperview];
                                    }];
}    
4

2 に答える 2

1

問題は 2 です。

  1. 画像リクエストを行うための呼び出しは、CPU % を占有します
  2. 画像のデコードには別の CPU % が必要です

画像サイズに応じて、さまざまなことを行う必要があります。最も簡単で明白な解決策は、別のスレッドで画像を解凍することです。これにより、メイン スレッドがブロックされず、スクロール パフォーマンスが大幅に向上します。

以下にコードのスニペットを示します。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^(void) {
                    UIImage *cellImage = [UIImage imageWithContentsOfFile:imgFilePath];
                    dispatch_async(dispatch_get_main_queue(),^ {
                        cellImageView.image = cellImage;
                    } );
                });

ご覧のとおり、UIImage はバックグラウンド スレッドで生成され、画像がデコードされるとすぐにセルに割り当てられます。

上記の例では、画像は事前にキャッシュされており、imgFilePath は画像がキャッシュされているドキュメント ディレクトリへのパスです。

Loren Brichter による ABTableView セル サブクラスを使用し、Core Graphics を使用して画像を描画するなど、他のさまざまなことで引き続きパフォーマンスを向上させることができます (パフォーマンスも大幅に向上します)。最後に、画像が巨大な場合は、セル全体を CATiledLayer クラスのサブクラスに設定して、画像の描画もシステムによってバックグラウンド スレッドで行われるようにすることができます...

于 2012-10-09T08:32:23.237 に答える
0

cellForRowAtIndexPath 内に画像をロードしないでください。それはあなたのスクロールを殺すだけです。

問題をすばやく解決するには、テーブルビューがスクロールしておらず、完全に停止している場合にのみ画像を読み込みます。

より良い方法は、デザインを再考することです。Network Queues と遅延読み込みイメージを使用する方法が最適です。

Lazy TableView の Apple デモを確認してください: http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html

これは私に多くのことを教えてくれました。あなたのように ASIHTTPRequest を使用することで、これをより簡単にすることさえできます。しかし、コードを見てください、それはよくコメントされており、理解しやすいです

** afnetwork を使用しているため更新

これを行います。cellForRowAtIndexPath 内:

NSURLRequest *imagerequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/image.png"]];
AFImageRequestOperation *op = [AFImageRequestOperation imageRequestOperationWithRequest:imagerequest success:^(UIImage *image) {
    cell.imageview.image = image;
}];
于 2012-10-09T07:54:55.093 に答える