簡體   English   中英

停止查詢Firebase?

[英]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
  • 此值(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM