每当我滚动我的tableview时,它都非常迟钝。我认为这与我如何加载我的细胞有关。我尽可能使用UINib(5.0+),同时仍然提供向后兼容性。然后我使用来自NSArray的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];
答案 0 :(得分:3)
正如@Till在评论中所说,你应该在乐器(产品 - &X; Xcode中的配置文件)中启动你的应用,然后选择CPU - > Time Profiler仪器。
然后,在该位置滚动几秒钟,然后点击乐器中的“录制”工具栏图标以关闭您的应用。您将能够看到滚动部分,因为CPU使用率可能会固定为100%(除非由于网络活动问题而导致速度很慢)。
单击高CPU活动区域开始后的时间线,然后单击“开始检查范围”工具栏按钮,然后在高CPU活动区域结束前单击并单击“停止检查范围”工具栏按钮。
现在,您可以深入查看窗口底部的调用树视图,以确切了解所有CPU使用情况。根据我的经验,如果关闭左侧的“反向调用树”选项,通常更容易找到问题。
性能错误很难找到,有时候一行显然很慢的代码根本不会导致任何问题。解决性能问题而不浪费时间的唯一方法是使用Instruments。
答案 1 :(得分:2)
确保您已将单元格的重用标识符设置为您在代码中指定的相同内容,即@"Cell"
。如果它们不匹配,那么你将不会正确地重复使用单元格,并且可能花费更多时间来创建不必要的单元格。
如果您正确地回收了单元格,那么您应该看看 if (cell == nil) {...}
块之后的代码。一旦表创建了足够的单元格来填充屏幕(并且可能还有一两个),您将跳过整个块,因此滚动时大部分时间归因于此方法将归因于以下代码。知道myArray
是什么,如果它实际上是一个数组,那么objectForKey:
方法的作用会很有趣。没有别的东西看起来就好像需要花费很长时间,但找出周期的最佳方法是在仪器中分析你的代码。
答案 2 :(得分:1)
查看代码后的一些笔记:
roundCorneredImage:radius:
是否缓存了结果?如果没有,对每个单元执行CG调用肯定会出现瓶颈。 更新:使用工具确定,但可能更快(允许内存)将已处理的UIImage
存储在集合中,以便下次该方法可以再次将其拉出使用相同的参数调用。
您的所有UIImage
都可以在其他地方声明,然后以此方法显示。您当前的代码为每个单元格实例化了一个新的UIImage
,这也可能会阻碍您的滚动。 已更新:由于Image1.png
和Image2.png
基本上是静态的,您可以在界面中将它们声明为静态ivar,然后将它们分配给背景图像,而不是实例化{每次{1}}。
继承UIImage
并将其实例化而不是进入UITableViewCell
可能会更快。此外,您还可以将布局/数据逻辑与委托方法分开。我在UINib
子类中所做的Here's a gist。基本上,我将实体存储在单元格中,并且单元格知道它的标签等。这使得单元格布局逻辑不在我的数据源代码中。
您似乎正在使用UITableViewCell
作为数据源。如果该词典中有很多对象,使用NSDictionary
和CoreData
可能要快得多。关于此事Here's a good post。 更新:好的,这应该不是问题。
-
所以如果你删除了所有这些:
NSFetchedResultsController
它仍然滞后,让我们看看你的构造函数......这些行做了什么?
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;
}
另外,你没有使用任何透明图像或桌面单元格中的任何东西吗?众所周知,这会导致绘图滞后......
-
如果你理解这一点,会发生什么?
cell = [self CustomTableCell];
[self setCustomTableCell:nil];