Диспетчерские очереди - Вложенность, Оптимизация и Контроль - PullRequest
0 голосов
/ 25 апреля 2019

Могу ли я получить ваш совет по утвержденному подходу?

У меня есть четыре процесса, которые должны выполняться последовательно:

calculateProcess1()
calculateProcess2()
calculateProcess3()
calculateProcess4()

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

Запустите их как есть, и вот, они все одновременно срабатывают (какой сюрприз!).

Как сделать так, чтобы вызовы верхнего уровня выполнялись последовательно (как указано выше), и нужно ли мне вносить изменения в мои DispatchQueues в процессах обновления литералов, например ::

DispatchQueue.main.sync { 
     let progressPercentage = (day*100/365)
     self.progressLabel.text = String(Int(progressPercentage))+"%"  
}

Инициирующие процессы (вычисленияProcess1-4 ()) должны запускаться из основного. Это должно быть в ViewDidLoad, действие кнопки или какой самый безопасный метод?

Ответы [ 3 ]

2 голосов
/ 25 апреля 2019

Один из подходов заключается в использовании Operation и OperationQueue. Установка maxConcurrentOperationCount: Int в 1 на OperationQueue заставит операции выполняться последовательно, одна за другой.

(ранее назывался NSOperation и NSOperationQueue)

Этот пост может быть полезен: https://nshipster.com/nsoperation/

И, конечно, потрясающий сеанс WWDC15: Расширенные операции NSO

2 голосов
/ 25 апреля 2019

Если вы хотите сохранить простоту, вы можете предоставить блоки обратного вызова для ваших calculateProcess методов и просто вложить их.

calculateProcess1() {
    calculateProcess2() {
        calculateProcess3() {
            calculateProcess4() {}
        }
    }
}

Должно ли это быть во ViewDidLoad, действие кнопки или что наиболее безопасный метод?

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

2 голосов
/ 25 апреля 2019

1 - Не sync в главном потоке, так как это вызовет сбой во время выполнения, должно быть async

DispatchQueue.main.sync { 

2-

Следуетэто может быть в ViewDidLoad, действие кнопки или какой самый безопасный метод?

Вам решать, что здесь нет ничего, связанного с безопасностью, реализуйте его как ваш UX

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

...