Sti*_*Sti 6 key-value-observing ios swift
假设我有一个名为class的类Person,其中包含firstName和lastName.我正在使用reactiveCocoa框架监听这些变量的变化,但是假设我只使用内置的KVO监听,就像didSet{}.所以假设我有这个代码:
let firstName:String { didSet{ self.nameDidChange() }}
let lastName: String { didSet{ self.nameDidChange() }}
func nameDidChange(){ print("New name:", firstName, lastName}
Run Code Online (Sandbox Code Playgroud)
每当我更改名字或姓氏时,它都会自动调用该函数nameDidChange.我想知道,是如果有任何聪明的举动这里,以防止nameDidChange函数被调用连续两次当我改变了这两个firstName和lastName.
比方说,价值firstName是"Anders"和lastName是"Andersson",然后我运行此代码:
firstName = "Borat"
lastName = "Boratsson"
Run Code Online (Sandbox Code Playgroud)
nameDidChange将在这里被召唤两次."New name: Borat Andersson"然后它将首先打印出来"New name: Borat Boratsson".
在我简单的想法中,我想我可以创建一个叫做类似的函数nameIsChanging(),每当调用任何函数时调用它didSet,并启动一个0.1秒的计时器,然后调用nameDidChange(),但这两个didSets也会调用nameIsChanging,所以计时器将进行两次,并且两次都会点火.为了解决这个问题,我可以保持一个"全局" Timer,并让它自己失效并重新启动计数或类似的东西,但我越想到解决方案,他们就会得到更多的丑陋.这里有"最佳实践"吗?
我认为你走在正确的道路上。我认为您只需要延迟对名称更改的调用,直到用户“停止”输入。
像这样的东西:
var timer = Timer()
var firstName: String = "Clint" {
didSet {
timer.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false, block: { _ in
self.nameDidChange()
})
}
}
var secondName: String = "Eastwood" {
didSet {
timer.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false, block: { _ in
self.nameDidChange()
})
}
}
func nameDidChange() {
print(firstName + secondName)
}
Run Code Online (Sandbox Code Playgroud)
每次更改第一个或第二个名称时,它都会停止计时器并再等待 0.2 秒,直到提交名称更改。
编辑
在阅读 Adam Venturella 的评论后,我意识到这确实是一种去抖动技术。如果您想了解更多相关信息,用谷歌搜索这个概念会很有用。
这是一个简单的 Playground 来说明这个概念:
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
var timer: Timer? = nil
func nameDidChange() {
print("changed")
}
func debounce(seconds: TimeInterval, function: @escaping () -> Swift.Void ) {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: seconds, repeats: false, block: { _ in
function()
})
}
debounce(seconds: 0.2) { nameDidChange() }
debounce(seconds: 0.2) { nameDidChange() }
debounce(seconds: 0.2) { nameDidChange() }
debounce(seconds: 0.2) { nameDidChange() }
debounce(seconds: 0.2) { nameDidChange() }
debounce(seconds: 0.2) { nameDidChange() }
Run Code Online (Sandbox Code Playgroud)
输出:
changed
Run Code Online (Sandbox Code Playgroud)
nameDidChange 函数仅执行一次。
| 归档时间: |
|
| 查看次数: |
504 次 |
| 最近记录: |