Как остановить метод, пока он работает в swiftui - PullRequest
1 голос
/ 17 февраля 2020

У меня есть проблема, и я должен найти решение. Я должен немедленно остановить метод «Запуск», если пользователь нажимает кнопку «Отмена». Я еще не устранил проблему, потому что не могу заблокировать метод во время его выполнения, но только в конце или в начале выполнения.

ContentView:

Button(action: {
 self.Starting()
 DispatchQueue.main.asyncAfter(deadline: .init(uptimeNanoseconds: 0), execute: self.workItem)

}) {
    Text("START")
    }

Button(action: {
 self.workItem.cancel()
 }) {
      Text("CANCEL")
    }

Метод запуска :

 func Starting() {
    self.workItem = DispatchWorkItem {
        DispatchQueue.main.async {
            self.impostazioniChek=true
        }

        DispatchQueue.global().async {
            if (self.pm.MarksSwitch)
            {
                sleep(UInt32(self.MarksT))
                self.Marks()
            }

            if (self.pm.ReadySwitch)
            {
               sleep(UInt32(self.ReadyT))
                self.Ready()
            }

            self.Start()
            sleep(3)
            DispatchQueue.main.async {
                self.tm.start()
            }

        }
    }
 }

1 Ответ

0 голосов
/ 18 февраля 2020

Вы не можете отменить, потому что

1) почти все время рабочие элементы выполняются в основной очереди (UI), поэтому заблокируйте его

2) внутри рабочего элемента нет проверки для isCancelled. DispatchWorkItem.cancel () только помечает его как отмененный, но не останавливает выполнение, вы должны сделать это.

Так что для выполнения этой работы необходимо перенаправить все не-пользовательские интерфейсы, связанные с вашим рабочим элементом, в очередь .background явно.

Например. вместо

DispatchQueue.main.asyncAfter(deadline: .init(uptimeNanoseconds: 0), execute: self.workItem)

используйте

DispatchQueue.global(qos: .background).async { self.workItem }

Вместо

DispatchQueue.global().async {
    if (self.pm.MarksSwitch)

Просто используйте (потому что он уже в фоновом режиме)

if (self.pm.MarksSwitch)

и я не уверен, что это такое (вероятно, его также следует запускать в фоновой очереди)

self.tm.start()

И во второй раз добавить прерывание внутреннего блока при отмене обычной проверкой, как показано ниже

...
}
if self.workItem.isCancelled { // add as many such as needed
    return
}
if (self.pm.ReadySwitch)
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...