首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cellforRowAtIndexPath效率?

cellforRowAtIndexPath效率?
EN

Stack Overflow用户
提问于 2012-01-01 20:21:36
回答 3查看 1.3K关注 0票数 2

每当我滚动我的桌面视图,它是非常滞后的。我认为这与我如何加载我的细胞有关。我在可能的时候使用UINib (5.0+),同时仍然提供向后兼容性。然后加载自定义单元格的标签和图像,其中包含来自NSDictionary的项目,这些项来自NSArray,该项目是从ViewDidLoad中的NSUserDefaults加载的。

有什么方法可以提高cellForRowAtIndexPath的效率吗?

代码语言:javascript
复制
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil) {
        if ([self labelCellNib]) {
            [[self labelCellNib] instantiateWithOwner:self options:nil];
        } else {
            [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        }
        cell = [self CustomTableCell];
        [self setCustomTableCell:nil];
    }
    NSDictionary *dictionary = [myArray objectAtIndex:indexPath.row];
    NSData *data = [dictionary objectForKey:@"OCRImage"];
    cell.previewPicture.image = [self roundCorneredImage:[UIImage imageWithData:data] radius:60];

    cell.titleLabel.text = [dictionary objectForKey:@"Title"];
    cell.titleLabel.delegate = self;

    cell.dateLabel.text = [dictionary objectForKey:@"Date"];

    if (indexPath.row%2) {
        cell.backgroundImage.image = firstImage;
    }
    else {
        cell.backgroundImage.image = secondImage;
    }
    return cell;
}

编辑:

代码语言:javascript
复制
- (UIImage*)roundCorneredImage: (UIImage*)orig radius:(CGFloat) r {
    UIGraphicsBeginImageContextWithOptions(orig.size, NO, 0);
    [[UIBezierPath bezierPathWithRoundedRect:(CGRect){CGPointZero, orig.size} 
                                cornerRadius:r] addClip];
    [orig drawInRect:(CGRect){CGPointZero, orig.size}];
    UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

Edit2:这些是导致延迟的行:

代码语言:javascript
复制
NSData *data = [dictionary objectForKey:@"OCRImage"];
cell.previewPicture.image = [self roundCorneredImage:[UIImage imageWithData:data] radius:60];
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-01 20:32:08

在查看了您的代码之后,我的一些注释:

  1. roundCorneredImage:radius:缓存结果吗?如果不是,对每个单元执行CG调用肯定会造成瓶颈。更新:使用工具来确定,但它可能会更快(允许内存)将处理过的UIImage存储在集合中,以便下次使用相同参数调用该方法时可以再次取出它。
  2. 您的所有UIImage都可以在其他地方声明,然后在此方法中显示。当前代码为每个单元实例化一个新的UIImage,这也会限制滚动。更新:由于Image1.pngImage2.png基本上是静态的,您可以在您的接口中或作为静态ivar声明它们,然后将它们分配给背景图像,而不是每次实例化UIImage
  3. 子类UITableViewCell和实例化可能更快,而不是深入到UINib中。另外,您还可以将布局/数据逻辑与委托方法分离开来。我在我的这里有个要点子类中所做的事情。基本上,我用单元格存储实体,而单元格知道它的标签等等。这将使单元格布局逻辑远离我的数据源代码。
  4. 看起来,您使用的是NSDictionary作为数据源。如果字典中有很多对象,那么使用CoreDataNSFetchedResultsController可能要快得多。这是个很好的帖子在这件事上。更新: Ok,这不应该是个问题。

-

编辑

所以如果你删除了所有这些:

代码语言:javascript
复制
NSDictionary *dictionary = [myArray objectForKey:@"OCRImage"];
cell.previewPicture.image = [self roundCorneredImage:[UIImage imageWithData:data] radius:60];

if (indexPath.row%2) {
    cell.backgroundImage.image = firstImage;
}
else {
    cell.backgroundImage.image = secondImage;
}

它仍然滞后,让我们看看您的constructors...what,这些行做了吗?

代码语言:javascript
复制
cell = [self CustomTableCell];
[self setCustomTableCell:nil];

而且,您没有在表单元格中使用任何透明的图像或任何东西,对吗?这些都被认为是导致拉延滞后的原因。

-

编辑#2

如果你脱光衣服,会发生什么?

代码语言:javascript
复制
CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell == nil) {
    if ([self labelCellNib]) {
        [[self labelCellNib] instantiateWithOwner:self options:nil];
    } else {
        [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    }
    cell = [self CustomTableCell];
    [self setCustomTableCell:nil];
}

cell.titleLabel.text = [dictionary objectForKey:@"Title"];
票数 1
EN

Stack Overflow用户

发布于 2012-01-01 20:39:19

正如@Till在评论中所说的,您应该在“仪器”中启动您的应用程序(产品->配置文件在Xcode中),并选择CPU ->时间分析器仪器。

然后,在这个地方滚动几秒钟,然后点击工具条图标关闭你的应用程序。您将能够看到滚动部分,因为CPU使用率可能会固定在100% (除非由于网络活动问题而慢)。

单击高CPU活动区域开始后的时间线,单击“开始检查范围”工具栏按钮,然后单击高CPU活动区域结束之前的按钮,然后单击“停止检查范围”工具栏按钮。

现在,您可以深入到窗口底部的调用树视图中,以确定您所有CPU使用的确切位置。根据我的经验,如果在左边关闭“反向调用树”选项,通常更容易找到问题。

性能缺陷可能很难找到,有时一行明显缓慢的代码实际上根本不会造成任何问题。解决性能问题而不浪费时间的唯一方法是使用仪器。

票数 3
EN

Stack Overflow用户

发布于 2012-01-01 20:36:50

确保您已经将单元的重用标识符设置为代码中指定的相同内容,即@"Cell"。如果它们不匹配,那么您将无法正确地重用单元格,并且可能会花费更多的时间创建单元格。

如果您正在正确地回收单元格,那么您应该查看if (cell == nil) {...}块之后的代码。一旦表创建了足够多的单元格来填充屏幕(可能还有一两个单元格),您将跳过整个块,因此,在滚动时,大部分时间都可以归因于此方法,原因是下面的代码。很想知道myArray是什么,如果它实际上是一个数组,那么objectForKey:方法会做什么。没有其他的东西看起来需要很长时间,但是最好的方法是在仪器中分析你的代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8695295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档