Как я могу приостановить NSOperation в NSOperationQueue?

Мне нужно приостановить выполнение NSOperation, которое было вставлено в NSOperationQueue. Сейчас я отменяю все операции и перезапускаю их. Но это привело бы к некоторому дублированию выполняемого процесса. Я пробовал с флагом setSuspended NSOperationQueue. Но это не приостанавливает работу. Есть ли выход?


person Advaith    schedule 16.08.2012    source источник


Ответы (3)


см. это: Ссылка

А здесь из документы Apple:

Приостановка и возобновление очередей Если вы хотите временно остановить выполнение операций, вы можете приостановить соответствующую очередь операций с помощью метода setSuspended :.

Приостановка очереди не приводит к приостановке уже выполняемых операций в середине их задач. Он просто предотвращает планирование выполнения новых операций. Вы можете приостановить очередь в ответ на запрос пользователя о приостановке любой текущей работы, поскольку ожидается, что пользователь в конечном итоге захочет возобновить эту работу.

person brush51    schedule 16.08.2012
comment
Спасибо! Я пробовал реализовать как по вашей ссылке. Я добавил новую переменную с именем isPaused внутри NSOperation, и всякий раз, когда мне нужно приостановить операцию, я устанавливаю для нее значение YES. Внутри NSOperation я буду регулярно проверять значение isPaused. Как только я найду ответ «ДА», я выйду из цикла. Но у меня здесь серьезная проблема. Я пытаюсь установить значение isPaused из основного потока. Это может привести к некоторым состояниям гонки. Есть ли способ избавиться от условий гонки? Есть ли способ вызвать методы (для приостановки и возобновления) в том же потоке (а не в основном потоке)? - person Advaith; 16.08.2012
comment
@Advaith: если оба потока блокируют мьютекс перед чтением или записью в isPaused, вам не придется беспокоиться о гонках. - person Nate Kohl; 19.08.2012

Я не пробовал, но, наверное, начну с этого:

  • добавьте флаг isPaused в свой NSOperation подкласс
  • реализовать метод копирования / перемещения для данных операции
  • если приостановлено, setCancelled: (обратите внимание на это изменение в -main)
  • создать новую операцию, перемещающую состояние из приостановленной операции в новую операцию
  • отрегулируйте приоритет, чтобы изменить порядок операций в очереди, если хотите
  • добавить клон в очередь
  • возврат из -main, если в -main

обратите внимание, что это просто приостановит его. если вы действительно хотите приостановить и явно возобновить, вы должны вручную «новую операцию», когда захотите возобновить.

теперь, если вы наблюдаете или имеете особые доработки, у вас будут еще несколько проблем. для простых случаев этот подход работает нормально.

person justin    schedule 16.08.2012

В Swift 5 вы можете использовать свойство isSuspended для приостановки и возобновления OperationQueue, вы можете увидеть пример для большего понимания: -

let operationQueue = OperationQueue()

let op1 = BlockOperation {
    print("done")
}
let op2 = BlockOperation {
    print("op2")
}
let op3 = BlockOperation {
    print("op3")
}

op1.addDependency(op2)
operationQueue.addOperations([op1, op2, op3], waitUntilFinished: false)

operationQueue.isSuspended = true
print("operationQueue suspended")

if operationQueue.isSuspended {
    operationQueue.isSuspended = false
    print("operationQueue restarted")
}


OutPut:- 
op2
op3
operationQueue suspended
operationQueue restarted
done
person Vipul Kumar    schedule 16.07.2020