//关联`debounceAsyncAfter` 的调用的键。
struct DebounceKey: Equatable, Hashable {
fileprivate let lockedState = UnfairLockedState<UInt64>(0)
init() {}
static func == (lhs: DebounceKey, rhs: DebounceKey) -> Bool {
return lhs.lockedState === rhs.lockedState
}
func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(lockedState))
}
}
//限定时间内只发生一个去抖动的异步块
func debounceAsyncAfter(deadline: DispatchTime, key: DebounceKey, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping () -> Void) {
let epoch = key.lockedState.sync { (x) -> UInt64 in
x += 1
return x
}
asyncAfter(deadline: deadline, qos: qos, flags: flags) {
guard epoch == key.lockedState.sync({ $0 }) else { return }
work()
}
}
//限定时间内只发生去抖动的一组异步块
func debounceAsyncAfter(wallDeadline: DispatchWallTime, key: DebounceKey, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping () -> Void) {
let epoch = key.lockedState.sync { (x) -> UInt64 in
x += 1
return x
}
asyncAfter(wallDeadline: wallDeadline, qos: qos, flags: flags) {
guard epoch == key.lockedState.sync({ $0 }) else { return }
work()
}
}