每当我滚动我的桌面视图,它是非常滞后的。我认为这与我如何加载我的细胞有关。我在可能的时候使用UINib (5.0+),同时仍然提供向后兼容性。然后加载自定义单元格的标签和图像,其中包含来自NSDictionary的项目,这些项来自NSArray,该项目是从ViewDidLoad中的NSUserDefaults加载的。
有什么方法可以提高cellForRowAtIndexPath的效率吗?
- (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;
}编辑:
- (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:这些是导致延迟的行:
NSData *data = [dictionary objectForKey:@"OCRImage"];
cell.previewPicture.image = [self roundCorneredImage:[UIImage imageWithData:data] radius:60];发布于 2012-01-01 20:32:08
在查看了您的代码之后,我的一些注释:
roundCorneredImage:radius:缓存结果吗?如果不是,对每个单元执行CG调用肯定会造成瓶颈。更新:使用工具来确定,但它可能会更快(允许内存)将处理过的UIImage存储在集合中,以便下次使用相同参数调用该方法时可以再次取出它。UIImage都可以在其他地方声明,然后在此方法中显示。当前代码为每个单元实例化一个新的UIImage,这也会限制滚动。更新:由于Image1.png和Image2.png基本上是静态的,您可以在您的接口中或作为静态ivar声明它们,然后将它们分配给背景图像,而不是每次实例化UIImage。UITableViewCell和实例化可能更快,而不是深入到UINib中。另外,您还可以将布局/数据逻辑与委托方法分离开来。我在我的这里有个要点子类中所做的事情。基本上,我用单元格存储实体,而单元格知道它的标签等等。这将使单元格布局逻辑远离我的数据源代码。NSDictionary作为数据源。如果字典中有很多对象,那么使用CoreData和NSFetchedResultsController可能要快得多。这是个很好的帖子在这件事上。更新: Ok,这不应该是个问题。-
编辑
所以如果你删除了所有这些:
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,这些行做了吗?
cell = [self CustomTableCell];
[self setCustomTableCell:nil];而且,您没有在表单元格中使用任何透明的图像或任何东西,对吗?这些都被认为是导致拉延滞后的原因。
-
编辑#2
如果你脱光衣服,会发生什么?
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"];发布于 2012-01-01 20:39:19
正如@Till在评论中所说的,您应该在“仪器”中启动您的应用程序(产品->配置文件在Xcode中),并选择CPU ->时间分析器仪器。
然后,在这个地方滚动几秒钟,然后点击工具条图标关闭你的应用程序。您将能够看到滚动部分,因为CPU使用率可能会固定在100% (除非由于网络活动问题而慢)。
单击高CPU活动区域开始后的时间线,单击“开始检查范围”工具栏按钮,然后单击高CPU活动区域结束之前的按钮,然后单击“停止检查范围”工具栏按钮。
现在,您可以深入到窗口底部的调用树视图中,以确定您所有CPU使用的确切位置。根据我的经验,如果在左边关闭“反向调用树”选项,通常更容易找到问题。
性能缺陷可能很难找到,有时一行明显缓慢的代码实际上根本不会造成任何问题。解决性能问题而不浪费时间的唯一方法是使用仪器。
发布于 2012-01-01 20:36:50
确保您已经将单元的重用标识符设置为代码中指定的相同内容,即@"Cell"。如果它们不匹配,那么您将无法正确地重用单元格,并且可能会花费更多的时间创建单元格。
如果您正在正确地回收单元格,那么您应该查看if (cell == nil) {...}块之后的代码。一旦表创建了足够多的单元格来填充屏幕(可能还有一两个单元格),您将跳过整个块,因此,在滚动时,大部分时间都可以归因于此方法,原因是下面的代码。很想知道myArray是什么,如果它实际上是一个数组,那么objectForKey:方法会做什么。没有其他的东西看起来需要很长时间,但是最好的方法是在仪器中分析你的代码。
https://stackoverflow.com/questions/8695295
复制相似问题