ios - 注册我不使用的单元格对性能有很大影响吗?

标签 ios swift swift3

我有我的 UITableViewCells在单独的 xib 中,因为我在整个应用程序中多次重复使用它们。我现在有一个小的单元格列表要在每个 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

我必须先将任何新单元添加到此列表中,然后才能使用该 Controller 中的单元,这很烦人且容易忘记。除此之外,在我的 viewDidLoad 中注册一个单元格列表是丑陋的,并且在某些地方它变得很长。
所以我想让它变得更好。我想在 UITableViewController 中做一个小功能注册我拥有的所有单元格的扩展名。这意味着只需要维护一个列表,而且还要在该特定 Controller 中注册我可能不需要的单元格。注册不必要的单元格是否会影响(大)性能?还有其他缺点吗?什么是最佳实践?

最佳答案

有两种方式会让你付出代价 - 在 vi​​ewDidLoad 时间注册所有 Nib ,以及在 tableView(_:cellForRowAt:)您在哪里创建/回收您的细胞。

1.在 View 中DidLoad

让我们详细看一下这条线:

tableView.register(UINib(nibName: "KeyTextCell", bundle: nil), forCellReuseIdentifier: "KeyTextCell")

这里发生了两件事:
  • 创建 UINib对象

  • 创建 UINib非常快 - 它甚至不会检查 Nib 是否存在,直到您要求它的内容。您可以使用以下代码进行测试:
    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: [:])
    

    此外,阅读 UINIb 的文档会告诉您它从磁盘加载内容一次并缓存它,因此无论您从 Nib 创建单元格多少次,您都只会在第一次需要时访问。
  • 将它注册到表 View

  • 这几乎是将一个项目插入到字典中——考虑到你的字典会有多小(7 个项目?),这会很快。所以我不会担心注册时间(不过,你应该测试一下,见下文)。

    2.在tableView(_:cellFrorRowAt:)

    tableView(_:cellFrorRowAt:) 中创建/出列一个单元格怎么样? ?我们可以忽略对现有单元格的出列——这与从 Nib 加载单元格无关——该单元格已经加载并在内存中——所以我们只关心当你请求一个单元格而没有一个准备好的时候被回收。给定平均表 View 高度,对于第一个充满行的屏幕,这将发生 10-15 次。在那之后,他们将开始回收。

    如果我们假设 tableViews 将它们的 Nib 存储在像字典这样的东西中,这将非常快 - 字典访问是 O(1) 所以你注册多少个单元格并不重要。但是,如果它存储为数组或集合之类的东西,那么随着您添加更多项目,访问速度会变慢,但您只添加了 7 个项目,因此它仍然非常快:)

    3. 测试这一切

    这主要是猜测 - 找出影响的最佳方法是在真实设备上对其进行测试(选择您的客户可能使用的最糟糕的设备!)

    测试这个的肮脏方法是只注册 10000 个 Nib (在 viewDidLoad 中编写一个循环)并查看您的应用程序的执行情况。如果 10,000 没问题,那么 7 就可以了;)

    测试它的最好方法是使用 Instruments 对其进行分析 - 通过按 CMD-i(而不是 CMD+r)在 Instruments 中运行您的代码,并且仪器将打开。选择“Time Profiler”并按下左上角的红色记录按钮 - 这将运行您的应用程序,但会在发生时记录所有方法调用等。让应用程序启动并稳定下来(事件图会在您的应用程序启动时进入心理状态,然后在您的应用程序坐在那里等待您与之交互时应该消失)。然后你可以导航到一个注册了所有这些 Nib 的 View Controller ,你可以看到打开 View Controller 需要多少事件,滚动需要多少事件等。试试这个,只注册一个 Nib ,然后试试10000注册看区别。

    您还可以在屏幕的下半部分看到按时间分割的函数调用 - 如果您点击那里,您可以找到一些关于哪些调用花费了很长时间的有用信息。

    希望这是有帮助的 - Instruments 可以做很多更有用的事情 - 值得点击一下并查看可用的内容。这里有文档:https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html

    要考虑的另一件事是内存 - 如果您在所有表格 View 中注册所有这些 Nib ,那么您可能正在使用您不需要的内存,但我会再次在乐器中对其进行分析,看看命中是什么。我的直觉是你不必担心,UINIb 只加载它需要的东西,我敢打赌,当内存不足警告到来时,UINIb 会清除它的缓存:)

    tl;dr 如果您的应用滚动顺畅,我不会担心 7 个 Nib 。

    关于ios - 注册我不使用的单元格对性能有很大影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44756402/

    相关文章:

    iphone - 固定表格 View 部分标题行的任何方法

    ios - uiwebview 换行长字

    ios - 单击可扩展 TableView 中的子菜单时,我们可以导航到新 View 吗?

    swift - 使用 CharacterSet 拆分字符串

    IOS Xcode 构建错误

    ios - 拒绝状态为 "Waiting For Review"的 iPhone 应用程序的二进制文件会导致什么情况?

    ios-如何将导航 Controller 添加到项目中?

    ios - 为什么我的 UISlider 没有动画?

    ios - 无法使用 (UnsafeMutableRawPointer) 类型的参数列表调用类型 UnsafePointer<_> 的初始值设定项

    ios - 如何获得星期一 00 :00 of current week? Swift 3