Как гарантировать, что одна функция выполняется за другой в Grand Central Dispatch? - PullRequest
0 голосов
/ 24 июня 2019

Как правило, я хочу загрузить несколько изображений, прежде чем запускать другие функции, которые зависят от загружаемого изображения.Я думаю, что у меня может быть неправильное понимание того, что такое GCD / как работают потоки.Я хочу, чтобы функции 1 и 2 происходили ПОСЛЕ того, как я загружаю изображения.Они оба выполняются быстро, но в значительной степени полагаются на загрузку изображений для завершения.Может быть, мне не следует использовать GCD (поскольку я хочу реализовать индикатор ожидания)?Я просто не могу заставить его работать должным образом

        if goToHome {
            DispatchQueue.global().async {
                DispatchQueue.main.sync {
                    self.uploadImages() // Uploads the images, takes a good amount of time to execute
                    function1()
                    function2()


                }
            }

Функции 1 и 2 продолжают работать до завершения загрузки изображений, поскольку для их выполнения требуется гораздо меньше времени.

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

Основной шаблон в Swift - выполнять работу, такую ​​как загрузка в фоновом потоке, затем вызывать функцию завершения в главном потоке и продолжать работу в зависимости от того, успешно ли завершена загрузка.

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

Так что-то вроде этого:

func uploadInBackground(_ images: [Image], completion: @escaping (_ success: Bool) -> Void) {
    DispatchQueue.global(qos: .background).async {
        var success = true

        // upload the images but stop on any error
        for image in images {
            success = uploadImage(image) // upload your images somehow

            guard success else { break }
        }

        DispatchQueue.main.async {
            completion(success)
        }
   }
}

func mainThreadUploader() {
    let images = [Image(), Image()] // get your images from somewhere

    // we are on the main thread where UI operations are ok, so:
    startProgressIndicator()

    uploadInBackground(images) { success in
        // this callback is called on the main thread, so:
        stopProgressIndicator()

        guard success else { return }

        // images uploaded ok, so proceed with functions that depend on
        // the upload(s) completing successfully:
        function1()
        function2()
    }
}
0 голосов
/ 24 июня 2019

Несмотря на запуск функции загрузки изображений в основной очереди, сама функция загрузки изображений выполняет операции в фоновой очереди. Чтобы это исправить, возможны следующие стратегии:

  • используйте обработчик завершения с загрузкой изображения, вероятно, самый простой для реализации в зависимости от реализации функции self.uploadImages()
  • заставить загрузку изображений происходить в главном потоке, что, вероятно, сложно реализовать и нецелесообразно
  • использовать группу рассылки, с которой у меня лично меньше опыта, но есть вариант
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...