0

我有一个使用reuseCellIdentifier 并包含图像的UITableView(使用UIImageView+AFNetworking.h 异步下载);正如所料,滚动一段时间后,当表格变长时,它会变得迟缓。我还将从 Internet 下载的每个单元格的数据存储在一个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...

更进一步,我还尝试在刷新时删除 tableview,如下所示,但这也无济于事......

-(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 是图像被缓存的 docments 目录的路径。

您可以通过其他各种方式继续提高性能,例如使用 Loren Brichter 的 ABTableView 单元子类并使用 Core Graphics 绘制图像(也大大提高了性能)。最后,如果图像很大,您可以将整个单元格设置为 CATiledLayer 类的子类,这样图像的绘制也可以由系统在后台线程中完成...

于 2012-10-09T08:32:23.237 回答
0

不要在 cellForRowAtIndexPath 中加载图像。那只会杀死你的滚动。

要快速解决您的问题,请仅在 tableview 未滚动、完全停止时才加载图像。

更好的方法是重新思考你的设计。通过使用网络队列和延迟加载图像是要走的路。

查看 Lazy TableView 的苹果演示:http: //developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html

这教会了我很多,通过像你一样使用 ASIHTTPRequest,你甚至可以让这更简单。但是看代码,注释很好,很容易理解

** 更新,因为您使用的是 afnetwork

做这个 f.ex。在你的 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 回答