How can I debounce a method call?

前端 未结 13 1454
醉梦人生
醉梦人生 2020-11-30 01:18

I\'m trying to use a UISearchView to query google places. In doing so, on text change calls for my UISearchBar, I\'m making a request to google pla

相关标签:
13条回答
  • 2020-11-30 02:03

    The following is working for me:

    Add the below to some file within your project (I maintain a 'SwiftExtensions.swift' file for things like this):

    // Encapsulate a callback in a way that we can use it with NSTimer.
    class Callback {
        let handler:()->()
        init(_ handler:()->()) {
            self.handler = handler
        }
        @objc func go() {
            handler()
        }
    }
    
    // Return a function which debounces a callback, 
    // to be called at most once within `delay` seconds.
    // If called again within that time, cancels the original call and reschedules.
    func debounce(delay:NSTimeInterval, action:()->()) -> ()->() {
        let callback = Callback(action)
        var timer: NSTimer?
        return {
            // if calling again, invalidate the last timer
            if let timer = timer {
                timer.invalidate()
            }
            timer = NSTimer(timeInterval: delay, target: callback, selector: "go", userInfo: nil, repeats: false)
            NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSDefaultRunLoopMode)
        }
    }
    

    Then set it up in your classes:

    class SomeClass {
        ...
        // set up the debounced save method
        private var lazy debouncedSave: () -> () = debounce(1, self.save)
        private func save() {
            // ... actual save code here ...
        }
        ...
        func doSomething() {
            ...
            debouncedSave()
        }
    }
    

    You can now call someClass.doSomething() repeatedly and it will only save once per second.

    0 讨论(0)
提交回复
热议问题