【问题标题】:scrolling on tableView is so slow在 tableView 上滚动太慢了
【发布时间】:2012-01-29 19:15:38
【问题描述】:

我有一个表格视图,后面有图像和文本,我创建如下代码的单元格:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];

    }

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    NSDictionary * companyProductRow = [DB getCompanyProductRow:[self.companyProductIDs objectAtIndex:indexPath.row]];

    int companyProductID = [[companyProductRow objectForKey:@"ID"] intValue];

    cell.tag = companyProductID;

    cell.textLabel.text = [companyProductRow objectForKey:@"ImagePath"];

    NSString* fullPath = [FileManager fullPath:companyProductID fairDirectory:[[self.currentFair objectForKey:@"ID"]intValue]];

    [[cell imageView] setImage:[UIImage imageWithContentsOfFile:fullPath]];

    return cell;
}

我在苹果开发者网站上阅读了一些关于 tableview 性能的提示,但他们都说: 重复使用细胞。对象分配有性能成本,特别是如果分配必须在短时间内重复发生 - 例如,当用户滚动表视图时。如果您重用单元格而不是分配新单元格,则可以大大提高表格视图的性能。 避免重新布局内容。当重用具有自定义子视图的单元格时,请避免在每次表格视图请求单元格时布置这些子视图。创建单元格时,布置一次子视图。 使用不透明的子视图。自定义表格视图单元格时,使单元格的子视图不透明,不透明。

apple 站点中的示例是相同的,但我想知道在 uitableview 上滚动时有什么方法可以提高性能吗? (当我们应该从磁盘读取图像时)。

谢谢

【问题讨论】:

    标签: ios


    【解决方案1】:

    是的。
    您可以增强的第一件事是图像加载。
    尽量避免使用[UIImage imageWithContentsOfFile:fullPath],因为它总是将整个图像加载到内存中。这实际上很慢。请改用[UIImage imageNamed:"YOUR_IMGAES_NAME"],因为它会在第一次使用后缓存图像或将它们直接预加载/存储在文件管理器中。

    下一步是将单元格中的所有视图设置为nil(如 imageView)并手动绘制所有内容。原因是UIViews 非常慢。如果您有很多标签、图像等要显示,那么手动绘制所有内容会快得多。

    【讨论】:

    • 谢谢你的回复,你能解释一下吗,图像在磁盘上,我有完整的图像路径,我认为路径不适用于“imageNamed”...?
    • 如果您的图像很小(我假设为 tableViewCell),我会在应用程序启动时将它们全部加载到内存中。只需创建一个数组并将带有imageWithContentsOfFile: 的图像加载到其中。一个好地方就是你的 FileManager。但我宁愿将所有图像添加到项目中,仍然使用[UIImage imageNamed:]
    【解决方案2】:

    您的tableView:cellForRowAtIndexPath: 看起来它正在为每个单元格进行 2 次磁盘读取,其中一次来自您的 [DB getCompanyProductRow:...],我认为这是某种数据库获取,第二次来自 [UIImage imageWithContentsOfFile:...]

    tableView:cellForRowAtIndexPath: 被调用之前(最好在[tableview reloadData] 之前)找到将这些信息加载到内存的方法。

    大型数据集的提示:

    如果您需要获取的数据太大而无法将内存加载到数组中,请尝试实现一些分页机制,以便您只需要显示该数据的子集。我什至建议您改用 Core Data 的 NSFetchedResultsController,但前提是您的数据库结构与对象模型兼容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      相关资源
      最近更新 更多