以编程方式创建 UITableViewCell 或从 nib 加载是不是更快?
Posted
技术标签:
【中文标题】以编程方式创建 UITableViewCell 或从 nib 加载是不是更快?【英文标题】:Is it faster to create UITableViewCell programmatically or load one from a nib?以编程方式创建 UITableViewCell 或从 nib 加载是否更快? 【发布时间】:2011-12-13 05:24:08 【问题描述】:时间分析器显示我的应用程序中最耗时的操作是从 nib 文件加载 UITableViewCells
。其中最昂贵的方法是加载带有 4KB 图像的UITableViewCell
。
我正在使用以下代码从笔尖加载UITableViewCell
:
[[NSBundle mainBundle] loadNibNamed:@"UITableViewCellPortrait" owner:self options:NULL];
cell = portraitCell;
self.portraitCell = nil;
有没有人比较过以编程方式创建视图或从 nib 加载 UITableViewCell
之间的区别?
编辑:
我比较了从笔尖加载UITableViewCell
并以编程方式创建视图的重复运行的时间曲线。我的测试涉及在 3-5 秒内交替使用两个 UITableViews
大约 10 次。在每次测试中,以编程方式加载 UITableViewCell
的速度要快得多,快 2 到 6 倍。
谁能证实这些结果?
编辑: 我更新了 nib 加载代码,只加载一次 nib 文件,并为后续调用使用缓存版本。
if (self.UITableViewPortaitNib == nil)
self.UITableViewPortaitNib = [UINib nibWithNibName:@"UITableViewCellPortrait" bundle:[NSBundle mainBundle]];
self.UITableViewPortaitNib instantiateWithOwner:self options:NULL];
cell = portraitCell;
self.portraitCell = nil;
我还使用自动化工具来创建更一致的运行,结果仍然表明以编程方式加载 UITableViewCells
比加载 nib 的 UITableViewCells
更快。从 nib 加载 UITableViewCells
的平均运行时间约为 90 毫秒,而以编程方式创建 UITableViewCell
的平均运行时间为 50 毫秒。
【问题讨论】:
向我们展示您的笔尖加载代码。 感谢您查看@robmayoff。我更新了问题以包括我的加载笔尖的代码。 有趣的发现 - 你能否使用故事板和原型单元再次运行实验,表格视图在后台加载所有笔尖? 我不知道 UIKit 是线程安全的。有没有其他人尝试在后台加载 nib 文件? 【参考方案1】:尝试创建一次UINib
对象,然后在每次需要创建新单元格时发送instantiateWithOwner:options:
。来自UINib Class Reference:
例如,如果您的表格视图使用 nib 文件来实例化表格视图单元格,则将 nib 缓存在
UINib
对象中可以显着提高性能。
【讨论】:
哇,帮了大忙!使用您提到的技术从 NIB 加载时,平均运行时间(对于有神论者的持续时间)从大约 300 毫秒下降到 90 毫秒。以编程方式加载,平均运行时间约为 50 毫秒。【参考方案2】:在 ios 5 和 WWDC 2011 视频中提到,有一种使用 UINib 的更新方法。您在viewDidLoad:
方法中注册您的笔尖,然后在tableView:cellForRowAtIndexPath:
方法中简化代码。这可能会为您加快速度(但我从未执行过任何比较时间)。
示例:
在您的viewDidLoad:
中注册笔尖并保留对它的引用:
NSString *myIdentifier = @"ReusableCustomCell";
[self.reuseCustomCell registerNib:[UINib nibWithNibName:@"ReusableCustomCell" bundle:nil] forCellReuseIdentifier:myIdentifier];
在您的tableView:cellForRowAtIndexPath:
方法中,只需询问单元格(无需检查 nil,因为它保证在 iOS5 下返回单元格)并配置单元格:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *myIdentifier = @"ReusableCustomCell";
ReusableCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:myIdentifier];
// Your configuration code goes here
cell.nameLabel.text = @"some text";
// ....
return cell;
代码未经测试。如果这比单独使用 UINib 更快,我会很感兴趣。
【讨论】:
这与我在第二次编辑中使用 UINib 基本相同。我无法想象它会更快,但编程肯定更好。从现在开始我会这样做 - 谢谢! “self.reuseCustomCell”指的是什么? self.reuseCustomCell 是一个类似于@property (nonatomic, strong) id reuseCustomCell; 的属性【参考方案3】:我只加载一次 nib 单元格 (cellTemplate
) 并根据需要复制它,所以从某种意义上说,这种方法既是编程的,也是基于 nib 的。
复制比我预期的要复杂,因为mutableCopy
不起作用。但是,NSKeyedArchiver
往返确实:
NSData* cellData = [NSKeyedArchiver archivedDataWithRootObject:cellTemplate];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:cellData];
事实上,如果您追求原始、炽热、踏板到金属的速度,即使是存档的模板也可以计算一次并缓存。
但是您不应该测量帧速率吗?在这种情况下,UIView 的复杂性也会发挥作用。
【讨论】:
明天早上我要试试keyed归档方法。您谈到了关于帧速率的一个好点。我开始分析 UITableViewCells 的最快方法的原因是因为我的方向变化动画非常慢。在这个动画中,我在两个 UITableViewControllers 之间转换,时间分析器突出显示了当我加载 UITableViewCells 时发生的最重的堆栈跟踪。您对如何加快帧速率有什么建议吗?【参考方案4】:可以重复使用加载后的 uitableviewcell 笔尖,然后它们会离开视图。阅读以下内容:
iPhone - What are reuseIdentifiers (UITableViewCell)?
【讨论】:
桑杰说得很好。在我的 nib 加载代码上方几行,我检查了具有适当重用标识符的单元格。以上是关于以编程方式创建 UITableViewCell 或从 nib 加载是不是更快?的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式计算 UITableViewCell 高度包含“<br>”或“\n”的文本
以编程方式在 UITableViewCell 内创建 UIScrollView - ScrollView 不滚动
UITableView 滚动后以编程方式创建的 UITableViewCell 未正确显示
如何使用自动调整其高度的 SnapKit 以编程方式创建 UITableViewCell?