我有UITableViewCells单独的 xib,因为我在我的应用程序中多次重复使用它们。我现在有一个要在 every 中注册的单元格的小列表UITableViewController,如下所示:
// viewdidload
tableView.register(UINib(nibName: "KeyTextCell", bundle: nil), forCellReuseIdentifier: "KeyTextCell")
tableView.register(UINib(nibName: "KeyValueCell", bundle: nil), forCellReuseIdentifier: "KeyValueCell")
tableView.register(UINib(nibName: "KeyEditFieldCell", bundle: nil), forCellReuseIdentifier: "KeyEditFieldCell")
tableView.register(UINib(nibName: "KeyTwoEditFieldCell", bundle: nil), forCellReuseIdentifier: "KeyTwoEditFieldCell")
tableView.register(UINib(nibName: "KeyThreeEditFieldCell", bundle: nil), forCellReuseIdentifier: "KeyThreeEditFieldCell")
tableView.register(UINib(nibName: "KeySwitchCell", bundle: nil), forCellReuseIdentifier: "KeySwitchCell")
tableView.register(UINib(nibName: "TextCell", bundle: nil), forCellReuseIdentifier: "TextCell")
//cellForRow...
let cell = tableView.dequeueReusableCell(withIdentifier: "KeyValueCell") as! KeyValueCell
Run Code Online (Sandbox Code Playgroud)
我必须先将任何新单元添加到此列表中,然后才能在该控制器中使用该单元,这很烦人并且很容易忘记。除此之外,在我的 viewDidLoad 中注册一个单元格列表是很丑陋的,而且在某些地方它会变得很长。
所以我想让这变得更好。我正在考虑在UITableViewController扩展中创建一个小函数来注册我拥有的所有单元格。这意味着只需维护一个列表,而且还要注册该特定控制器中可能不需要的单元格。注册不必要的单元是否会对性能造成(大)影响?还有其他缺点吗?最佳实践是什么?
有两种方式会让你付出代价 - 在 viewDidLoad 时注册所有笔尖,以及在tableView(_:cellForRowAt:)创建/回收单元格时。
1.在viewDidLoad中
让我们详细看看该行:
tableView.register(UINib(nibName: "KeyTextCell", bundle: nil), forCellReuseIdentifier: "KeyTextCell")
Run Code Online (Sandbox Code Playgroud)
这里发生了两件事:
UINib对象创建一个UINib非常快 - 它甚至不会检查笔尖是否存在,直到您询问它的内容。您可以使用以下代码进行测试:
let nib = UINib(nibName: "Doesn't exist", bundle: nil)
print(nib) // Prints out something like `<UINib: 0x60000001fba0>`
// This line will load the nib and unpack it into the view.
// It's obviously going to fail :)
let view = nib.instantiate(withOwner: nil, options: [:])
Run Code Online (Sandbox Code Playgroud)
另外,阅读 UINib 的文档会告诉您,它会从磁盘加载一次内容并将其缓存,因此无论您从 nib 创建单元格多少次,您都只会在第一次需要时访问。
这几乎相当于将一个项目插入到字典中 - 考虑到你的字典有多小(大约 7 个项目?),这会很快。所以我不会担心注册时间(不过,您应该对此进行测试,请参见下文)。
2. 在tableView(_:cellFrorRowAt:)
在 中创建/出队一个单元怎么样tableView(_:cellFrorRowAt:)?我们可以忽略使现有单元出列 - 这与从笔尖加载单元无关 - 该单元已经加载并在内存中 - 所以我们关心的是当您请求一个单元但没有准备好的单元时被回收。考虑到平均表视图高度,对于第一个充满行的屏幕,这种情况会发生 10-15 次。之后,他们将开始回收。
如果我们假设 tableViews 将它们的 nib 存储在类似字典的东西中,这将非常快 - 字典访问是 O(1),所以注册多少个单元格并不重要。然而,如果它存储为数组或集合之类的东西,那么当您添加更多项目时访问会变慢,但您只添加 7 个项目,所以它仍然相当快:)
3. 测试这一切
这主要是猜测 - 找出影响的最佳方法是在真实设备上进行测试(选择您的客户可能使用的最差设备!)
测试此功能的肮脏方法是仅注册 10000 个 nib(在 viewDidLoad 中编写循环)并查看应用程序的执行情况。如果 10,000 没问题,那么 7 也可以;)
测试此功能的最佳方法是使用 Instruments 对其进行分析 - 按 CMD-i(而不是 CMD+r)在 Instruments 中运行代码,然后 Instruments 将打开。选择“时间分析器”并按左上角的红色记录按钮 - 这将运行您的应用程序,但会记录所有发生的方法调用等。让应用程序启动并稳定下来(当您的应用程序启动时,活动图会进入心理状态,然后当您的应用程序只是坐在那里等待您与其交互时,活动图应该会下降到什么都没有)。然后,您可以导航到注册了所有这些笔尖的视图控制器,您可以看到打开视图控制器需要多少活动,以及滚动需要多少活动等。尝试仅注册一个笔尖,然后尝试使用注册10000就可以看到差别。
您还可以在屏幕下半部分看到按时间细分的函数调用 - 如果您单击此处,您可以找到一些有关哪些调用花费很长时间的有用信息。
希望这对您有所帮助 - Instruments 可以做很多更有用的事情 - 值得点击一下并查看可用的内容。这里有文档:https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html
另一件要考虑的事情是内存 - 如果您在所有表视图中注册所有这些笔尖,那么您可能会使用不需要的内存,但我会再次在仪器中对此进行分析,看看命中是什么。我的直觉是,你不必担心,UINib 只加载它需要的内容,而且我敢打赌,当内存不足警告到达时,UINib 会清除它的缓存:)
tl;dr 如果您的应用程序滚动顺畅,我不会担心 7 个笔尖。
| 归档时间: |
|
| 查看次数: |
528 次 |
| 最近记录: |