[英]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.