Отменить обработчик завершения (iOS)

У меня есть текстовое поле, которое извлекает данные из API каждый раз, когда текст textField изменяется, и обновляет таблицу.

override func viewDidLoad() {
    super.viewDidLoad()

    searchTextField.addTarget(self, action: #selector(textFieldDidChange), for: UIControlEvents.editingChanged)
}

func textFieldDidChange() {

    let queryString = self.searchTextField.text

    SearchWSFacade.getSearchResults(queryString: queryString) {
         (error) in

         if (error == nil) {
             self.tableView.reloadData()
         } 
    }
}

Это прекрасно работает, только если пользователь вводит медленно (позволяет загружать данные перед вводом следующего символа). Если пользователь печатает быстро, мы сталкиваемся с проблемами из-за нескольких вызовов reloadData.

Это можно было бы решить, если бы я отменил обработчик завершения при поиске, когда выполняется предыдущий поиск. Как мне это сделать? Или есть решение получше?


person Josh O'Connor    schedule 17.03.2017    source источник
comment
Вы можете проверить, совпадает ли строка запроса с текстом текстового поля, и не перезагружать таблицу, если они отличаются.   -  person dan    schedule 17.03.2017
comment
@dan простое, но эффективное решение. К сожалению, я не могу принять ваш комментарий как ответ.   -  person Josh O'Connor    schedule 17.03.2017
comment
Мой подход к этому - запускать таймер при изменении текста (скажем, на 0,5 секунды) и перезапускать таймер, когда текст снова изменяется. Только когда срабатывает таймер, я действительно выполняю операцию поиска.   -  person Paulw11    schedule 18.03.2017


Ответы (2)


Если вы используете операции, вы можете настроить зависимости так, чтобы одна не запускалась, пока не завершится следующая. И, в отличие от блоков, Операции можно отменить.

person Abizern    schedule 17.03.2017
comment
На самом деле это был мой следующий шаг, если бы у меня не было такого простого решения, как Дэн. Спасибо, Abizern. - person Josh O'Connor; 17.03.2017

Вы можете установить простой флаг в UIViewController, содержащем текстовое поле - возможно, busyCallingAPI - установить его true, когда вы запускаете вызов API, установить его false в обработчике завершения, а в textFieldDidChange выполнять вызов только в том случае, если busyCallingAPI ложно

person Russell    schedule 17.03.2017
comment
Я попытался использовать для этого логическое значение, однако проблема заключалась в том, что более длинные строки (поиск в процессе и в) извлекались быстрее, чем короткие. - person Josh O'Connor; 17.03.2017