【问题标题】:UITableView with huge number of image具有大量图像的 UITableView
【发布时间】:2019-09-11 09:32:01
【问题描述】:

我的应用需要在 UITableView 中显示大量图像(大约 2000 张)。基本上,我使用以下代码来构造我的 UITableViewCell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    } 

    // Some Operations...

    NSString *path = [self.dataArray jk_objectWithIndex:indexPath.row];
    UIImage *img = [UIImage imageWithContentsOfFile:path];
    cell.imageView.image = img;

    return cell;
}

这可行,但是当 tableview 加载时,内存会快速增加,并且似乎所有图像都已加载到内存中。

有什么好的想法来解决这个问题吗?我只是想节省内存。

顺便说一句,有谁知道实现这种需求的常用方法是什么?我认为将所有图像加载到内存是最愚蠢的方式......我最初的tableview行代码如下:


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (!_isLoading) {
        return self.dataArray.count; // about 2000... That's terrible
    } else {
        return 0;
    }
}

谢谢!

【问题讨论】:

  • 您的图片是来自本地还是 WebAPI?
  • 如果你想从服务器加载图像,请使用github.com/SDWebImage/SDWebImage
  • 我的图片来自本地。
  • 您遇到的问题来自图像缓存。每个图像都被缓存,它增加了使用的内存。我认为您可以尝试创建不同的图像缓存并清理远离表视图当前索引的缓存。
  • @m1sh0 感谢您的建议。当 tableview 没有出现在屏幕上时,一切正常。 dataArray 包含图像的路径,而不是图像本身。

标签: ios image uitableview


【解决方案1】:

您的代码有两个问题。

  • 首先,也是最重要的一点,图像很大,但表中图像的显示很小。那是错误的。您应该仅以实际显示所需的大小加载图像。

  • 其次,图片默认缓存。您需要防止在加载这些图像时对其进行缓存。

使用 ImageIO 框架,您可以在 cellForRowAt 中轻松完成这两件事。

【讨论】:

  • ImageIO默认可以防止缓存所有图片?
【解决方案2】:

我想出了解决这个问题的方法。将这几行代码添加到cellForRowAtIndexPath:

CGRect rectInTableView = [tableView rectForRowAtIndexPath:indexPath];
    CGRect rectInSuperview = [tableView convertRect:rectInTableView toView:[tableView superview]];
    if ( rectInSuperview.origin.y > SCREEN_HEIGHT || rectInSuperview.origin.y + rectInSuperview.size.height < 0 ) {
        cell.imageView.image = self.placeholder;
    } else {
        NSString *path = [self.dataArray jk_objectWithIndex:indexPath.row];
        UIImage *img = [UIImage imageWithContentsOfFile:path];
        cell.imageView.image = img;
    }

首先我检查单元格是否显示在屏幕上。如果是,则 imageView 显示我的数据图像。如果没有,它会显示占位符。此外,占位符初始化为[UIImage imageNamed:]。这是最好的方法,因为它会经常使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多