0

我正在处理的 iPad 应用程序有很大问题。我会向你解释什么是问题。

我有产品清单。我有表格视图来显示该产品。我尝试在横向模式下在一个单元格中加载 3 个图像(产品),在纵向模式下加载 2 个。为此,我在控制器类中使用此代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
  [cell setBackgroundColor:[UIColor clearColor]];

  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,  0ul);
  dispatch_async(queue, ^{

    for(int i = 0; i < self.cols; i++){
      int index = (indexPath.row * self.cols) + i;

      if([self.productList count] > 0 && index < [self.productList count]){
        Product *tmpProduct = nil;
        if([self.productList isKindOfClass:[NSMutableSet class]]){
          tmpProduct = (Product *)[[NSArray arrayWithArray:[((NSSet *)self.productList) allObjects]]  objectAtIndex:index];
        }else{
          tmpProduct = (Product *)[((NSArray *)self.productList) objectAtIndex:index];
        }

        int x = i * self.itemWidth + (50 * (i + 1));
        int y = 0;
        int imageWidth = self.itemWidth;
        int imageHeight = self.itemHeight - 45;

        UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(x, y, imageWidth, self.itemHeight)];
        awesomeView.backgroundColor = [UIColor clearColor];
        awesomeView.userInteractionEnabled = YES;
        awesomeView.tag = 700;

        UIImage *image;
        if([tmpProduct getImageFilePath]){
          image = [UIImage imageWithContentsOfFile:[tmpProduct getImageFilePath]];
        }else{
          image = [UIImage imageNamed:@"no-image.png"];
        }
        dispatch_sync(dispatch_get_main_queue(), ^{

          UIImageView *productImage = [[UIImageView alloc] initWithImage: image];
          CGRect frameRect = productImage.frame;
          frameRect.size.width = imageWidth;
          frameRect.size.height = imageHeight;
          productImage.frame = frameRect;
          productImage.contentMode = UIViewContentModeScaleAspectFill;
          productImage.tag = index;
          productImage.backgroundColor = [UIColor grayColor];
          productImage.contentMode = UIViewContentModeScaleAspectFit;

          [awesomeView addSubview:productImage];
          [cell.contentView addSubview:awesomeView];
          [cell setNeedsLayout];
        });

      }
    }
  });
  return cell;
}

您可以看到,当单元格要显示并调用“cellForRowAtIndexPath”方法时,我会启动后台队列。在一个单元格中为 3 或 2 个图像开始“for”。根据行获取该单元格的产品。计算图像的宽度和高度和位置。启动一个辅助视图。比加载图像。如果图像存在于产品对象中,我会加载产品图像,否则我会加载默认图像(无图像)。将该图像视图放在我的辅助视图中。之后,我将辅助视图加载到主队列中的单元格。(我使用那个帮助视图“awesomeView”,因为我有更多的东西要显示,一些标签,我删除了它以简化这个问题)。

这是我录制的 youtube 视频,以查看我遇到的问题。您可以看到,当我向上或向下滚动时,它非常缓慢。每次脚本加载下一个单元格时,它都会冻结部分秒。YOUTUBE 视频:http: //youtu.be/hE3KI0SVrPk

有人可以帮助我,我不知道我错在哪里。

我尝试了几种与队列的组合,也尝试了不使用队列的组合,结果几乎相同。

先谢谢了。

4

1 回答 1

2

正确的方法如下:

  • 创建一些可变集合来保存图像

  • 当你发现你需要一张图片,而它不在收藏中时,做(有点)你正在做的事情——在背景中获取图片

  • 保留您当前正在获取的内容的索引或某个 id,因此您不会多次执行此操作。

  • 当你得到图像时,然后 dispatch_async 到你的视图控制器中的一个方法

  • 接收方法接收图像,并检查表中的所有可见单元格(有一种方法),以查看图像是否适用于其中任何一个。如果是这样,它会更新该单元格。如果不是,它将图像放入可变集合中。

在我的情况下,我有一个已知的 productID,我可以将其用作与可变字典一起使用的键。我会在第一次获取图像时[NSNull null]为键的对象添加一个条目 - 这使得测试我是否已经在获取图像变得容易。获得图像后,图像替换了 nsnull 占位符。

于 2013-11-13T22:43:23.677 回答