DispatchWorkItem не отменяет задачу сразу - PullRequest
0 голосов
/ 27 февраля 2019

У меня неприятная проблема с поиском.

Существует массив структур с 30000 объектами и textView, при вводе букв я удаляю пробелы и задаю текст в searchText, searchText имеет WillSet и DidSet, вWillSet Я отменяю все задачи поиска со старым текстом и начинаю поиск с новым текстом в DidSet.в функции search() я прохожу массив и добавляю логику к DispatchWorkItem в функции anyTranslate(), searchText выдает ошибку - [CFString length]: message sent to deallocated instance, когда я набираю много символов.Я создал переменную типа test, которая не должна быть истинной в anyTranslate(), но иногда она выводит true, ошибка всегда появляется, только если test равен true, как я понимаю, DispatchWorkItem не отменяет все задачи сразу,

как я могу решить эту проблему?

static var splitArr = (first:[Words](),second:[Words](),third:[Words](), four:[Words](), five:[Words]()) // fragmented array for faster searching
var work:[DispatchWorkItem?] = [nil,nil,nil,nil,nil]
var test = false

private var searchText = "" {
    didSet{
        test = false
        if searchText.count >= 2 {
            self.search(nil)
        }
    }

    willSet{
        for (i,ind) in self.work.enumerated() {
            ind?.cancel()
            self.test = true
        }
    }
}

func search(_ completion:(() -> ())?){

    update = true
    words.removeAll()
    DispatchQueue.main.async {
        self.tableView.isUserInteractionEnabled = false
        self.indicator.isHidden = false
        self.indicator.startAnimating()
    }

    let arr = [ViewController.splitArr.first, ViewController.splitArr.second, ViewController.splitArr.third, ViewController.splitArr.four, ViewController.splitArr.five]

    for (i,value) in arr.enumerated() {

        work[i] = DispatchWorkItem { [weak self] in
            let lang = Language.first()
            for (index,words) in value.enumerated() {
                guard self?.work[i]?.isCancelled == false else { break }
                self?.anyTranslate(with: words, and: lang)
                if index == value.count - 1 {

                    DispatchQueue.main.async {
                        if self?.words.count == 0 {
                            self?.noFound()
                        }
                        self?.tableView.reloadData()
                        self?.tableView.isUserInteractionEnabled = true
                        self?.indicator.isHidden = false
                        self?.indicator.stopAnimating()
                        completion?()
                    }

                }
            }
        }

        guard let current = work[i] else { return }
        DispatchQueue.global(qos: .userInteractive).async(execute: current)

    }

}

func anyTranslate(with words: Words, and lang:String){

    let array = Language.getLang(lang: lang, word: words)
    for value in array[0] ?? [""] {
        if test == true {
            print(true)
        }
         // - [CFString length]: message sent to deallocated instance
        if value.hasPrefix(searchText) {
            addWord(with: words)
            return
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...