繁体   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