[英]Stopping a query to firebase?
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
} else {
if allInterestsArray.contains(searchBar.text!.lowercaseString) {
ref.child(searchBar.text!.lowercaseString).child("users")
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
print("this should be running")
print(searchBar.text!.lowercaseString)
let handle = roomsRef.observeSingleEventOfType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
print(snapshot.value)
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
print(snap)
}
}
})
}
}
else {
print("doesn't exist")
}
}
}
当searchBar.text等于allInterestsArray中的值时,我正在对Firebase数据库运行查询。 这是在击键时检查的,我正在使用dispatch_after来阻止发送查询,直到用户可能已经完成键入为止。
发生的情况是,如果我在“ Dog”数组中有该项目,并且用户进入“ dog”,然后键入“ s”,使其变为“ dogs”。查询仍然针对dog和然后是狗,因此我需要在textDidChange函数的顶部取消查询,我认为在每次击键时都将其取消,并且仅在经过一秒钟的无输入后才发送该查询。
我当时在考虑使用removeHandle,但我不认为这是用来做什么的?
例:
如果我的数组= [“ dog”,“ dogs”,“ doggies”]
用户输入的速度足够快,因此任何两个字母之间都不会有完整的1秒钟(由于我设置的dispatch_after时间,所以没有1秒钟),他们输入了“ dogs”。。对dog的查询不应只对“ dogs”有效”。
可以使用一个名为“ keepSearching”的全局变量来解决此问题,如下所示:
编辑:我现在也使用NSTimer为“ keepSearching”提供一秒钟的间隔为假。
var keepSearching: Bool = true
var timer = NSTimer()
func timerAction() {
keepSearching = false
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
}
else if(keepSearching) {
if allInterestsArray.contains(searchBar.text!.lowercaseString) {
// just in case user keeps on typing, invalidate the previous timer, before it happens.
timer.invalidate()
// schedule a new timer everytime.
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
ref.child(searchBar.text!.lowercaseString).child("users")
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
print("this should be running")
print(searchBar.text!.lowercaseString)
let handle = roomsRef.observeSingleEventOfType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in
print(snapshot.value)
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
print(snap)
}
}
})
}
}
else {
print("doesn't exist")
}
}
您可以添加一个属性,该属性在每次提交dispatch_after
块时都会增加,并检查该值是否对应于当前值。 这样,您就可以确定是否应该启动请求。 这是您的控制器类的外观(仅包括该问题的相关部分):
class MyController: <base class, protocols> {
var requestsCounter = 0
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
// mark that a new request is made
self.requestsCounter++
// save the number in a local var to be used when the block
// actually executes
let currentCounter = self.requestsCounter
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
} else {
dispatch_after(...) { () -> Void in
// if another dispatch_after was submitted, then the value of the
// currentCounter local variable won't match the property value,
// so we should no longer proceeed
guard currentCounter == self.requestsCounter else { return }
// ... the original code here
}
}
它是如何工作的:
requestsCounter
属性,因此现在它的值为1 currentCounter
,其值由dispatch_after
闭包捕获。 dispatch_after
执行闭包之前调用了委托方法,则requestsCounter
将增加为2,并且将使用第二个dispatch_after
闭包创建并捕获具有该值的新currentCounter
变量。 dispatch_after
闭包时,它捕获的currentCounter
值将保持为1,但是self.requestsCounter
将为2,因此闭包将返回而不进行实际工作 searchBar: textDidChange:
委托方法将增加每次requestsCounter
财产,这反过来会作废以前计划的封锁,因为每个捕捉的旧值requestsCounter
财产。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.