在tableView上滚动是如此之慢

时间:2012-01-29 10:50:10

标签: ios

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

- (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性能的提示,但他们都说: 重复使用细胞。对象分配具有性能成本,特别是如果分配必须在短时间内重复发生 - 例如,当用户滚动表视图时。如果重用单元而不是分配新单元,则可以极大地提高表视图性能。 避免重新播放内容。当重复使用具有自定义子视图的单元格时,每次表格视图请求单元格时都不要布置这些子视图。创建单元格时,布置子视图一次。 使用不透明的子视图。自定义表格视图单元格时,使单元格的子视图不透明,不透明。

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

非常感谢

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

你的tableView:cellForRowAtIndexPath:看起来正在为每个单元格执行2次磁盘读取,一次来自[DB getCompanyProductRow:...],我假设是某种数据库提取,第二次来自[UIImage imageWithContentsOfFile:...]

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

大型数据集的提示:

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