首页 > 解决方案 > 为什么 UITableView 在重新加载数据时会缓存单元格?

问题描述

如果您要tableView.reloadData()使用 custom 调用表格UITableViewCell,那么它会在您重新加载数据时缓存这些单元格。(这里讨论:https ://github.com/nicklockwood/FXForms/issues/92 )

如果您继续重新加载数据,一段时间后,可能会有 30/40 个单元被缓存和保留。我的问题是:为什么会这样?

尤其是:

1)有什么可能的用途可以保留重新加载表格后丢失的单元格?

2) 可以做些什么来防止/减少存储单元的内存缓存?

3)最重要的是,为什么会发生这种情况?为什么在调用时会保留单元格reloadData()

例子

给你一个基本的代码示例,单击其中一个单元格,然后,当你看到内存中的对象时,会有更多保留的单元格:

ViewController.Swift

import UIKit

class ViewController: UIViewController {
    let tableViewController = QuizTableViewController(style: .grouped)

override func viewDidLoad() {
    super.viewDidLoad()
    self.setupTableViewController()
}

private func setupTableViewController() {
    self.view.addSubview(tableViewController.view)

    let topAnchor = self.tableViewController.view.topAnchor.constraint(equalTo: self.view.topAnchor)
    let leadingAnchor = self.tableViewController.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor)
    let trailingAnchor = self.tableViewController.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
    let bottomAnchor = self.tableViewController.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
    NSLayoutConstraint.activate([topAnchor, leadingAnchor, trailingAnchor, bottomAnchor])
}
}

QuizTableViewController.Swift

import UIKit

class QuizTableViewController: UITableViewController {
override init(style: UITableViewStyle) {
    super.init(style: style)
    self.view.translatesAutoresizingMaskIntoConstraints = false
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 5
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 60
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = QuizCell(subText: "HELLO WORLD")
    cell.textLabel?.text = "THIS IS WHAT IS DISPLAYED"
    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.reloadData()
}
}

QuizCell.Swift

import UIKit

class QuizCell: UITableViewCell {
weak var subText: UILabel?

init(subText: String) {
    self.subText = UILabel()
    self.subText?.text = subText
    super.init(style: .default, reuseIdentifier: "QuizCell")
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

deinit {
    print("This is called after the cache is full.")
}
}

标签: iosswiftuitableview

解决方案


就像@rmaddy 提到的那样,问题在于您如何使单元格出队cellForRowAt。相反,将其更改为类似于:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "QuizCell", for: indexPath) as! QuizCell
    cell.textLabel?.text = "THIS IS WHAT IS DISPLAYED"
    return cell
}

推荐阅读