【发布时间】:2021-07-23 06:02:08
【问题描述】:
Diffable 数据源需要指定 SectionIdentifierType 和 ItemIdentifierType,这些类型必须符合 Hashable
假设它们必须符合Hashable,以便数据源可以进行差异化。
那么为什么即使 == 和散列函数相同,它的行为也会根据标识符类型是类还是结构而有所不同呢?或者甚至为类重写 === 函数,使其更像值类型?
例子:
import UIKit
public class DebugViewController: UIViewController {
typealias SectionType = IntWrapper
typealias ItemType = IntWrapper
public class IntWrapper: Hashable {
public static func == (lhs: DebugViewController.IntWrapper, rhs: DebugViewController.IntWrapper) -> Bool {
lhs.number == rhs.number
}
public static func === (lhs: DebugViewController.IntWrapper, rhs: DebugViewController.IntWrapper) -> Bool {
lhs.number == rhs.number
}
public func hash(into hasher: inout Hasher) {
hasher.combine(number)
}
var number: Int
init(number: Int) {
self.number = number
}
}
private var dataSource: UITableViewDiffableDataSource<SectionType, ItemType>!
@IBOutlet var tableView: UITableView!
public override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DefaultCell")
dataSource = UITableViewDiffableDataSource<SectionType, ItemType>(tableView: tableView) { (tableView, indexPath, item) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultCell")!
cell.textLabel?.text = "\(item.number)"
return cell
}
apply()
}
@IBAction func buttonTapped(_ sender: Any) {
apply()
}
func apply() {
var snapshot = NSDiffableDataSourceSnapshot<SectionType, ItemType>()
let sections = [IntWrapper(number: 0)]
let items = [IntWrapper(number: 1)]
snapshot.appendSections(sections)
sections.forEach { snapshot.appendItems( items, toSection: $0) }
dataSource.apply(snapshot, animatingDifferences: true)
}
}
如果IntWrapper 是一个结构,则在调用apply() 时表视图什么也不做(apply() 本质上是加载相同的数据)对我来说,这是预期的行为。
如果IntWrapper 是一个类,则在调用apply() 时表视图会重新加载。此外,甚至没有调用 hash() 和 == 函数。
除非有人可以访问源(提示、提示)或除非我在示例中犯了错误,否则我认为无法回答此问题。
【问题讨论】:
-
你有没有想过?我被困了 2 天试图弄清楚这一点
-
@gmogames 我只坚持尽可能使用
structs。当我向每个结构添加let id: UUID时,如果两个结构的数据可以相同,以便它们始终是唯一的。如果您获得两个具有相同数据的结构,则应用程序将崩溃。如果需要更新数据,我会创建一个具有相同 id 的新结构,但会更改值并将其添加到新快照中。
标签: ios swift diffabledatasource