Как создать очередь отправки в Swift 3

403

В Swift 2 мне удалось создать очередь со следующим кодом:

let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT)

Но это не компилируется в Swift 3.

Каков предпочтительный способ написать это в Swift 3?

Картик Кумар
источник
Swift 4 имеет 3 дополнительных параметра для создания последовательной очереди. Как использовать их для создания последовательной очереди? DispatchQueue.init (метка:, qos:, атрибуты:, autoreleaseFrequency:, target
:)
@ nr5 Очереди по умолчанию являются последовательными, поэтому достаточно просто использовать их DispatchQueue(label: "your-label")для последовательной очереди. Все дополнительные параметры имеют значения по умолчанию.
JBG

Ответы:

1132

Создание параллельной очереди

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}  

Создать последовательную очередь

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 

}

Получить основную очередь асинхронно

DispatchQueue.main.async {

}

Получить основную очередь синхронно

DispatchQueue.main.sync {

}

Чтобы получить один из фонового потока

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2 beta 2:

Чтобы получить один из фонового потока

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

Если вы хотите узнать об использовании этих очередей. Посмотрите этот ответ

Этот ленивый парень с iOS 웃
источник
4
Вы действительно можете пропустить attributes: .serialпри создании последовательной очереди: let serialQueue = DispatchQueue(label: "queuename").
Кина
15
В Xcode 8 beta 4 нет опции .serial, поэтому вы должны создать последовательную очередь, пропустив .concurrent в атрибутах.
Олег Шерман
Мне нужно получить доступ к DispatchQueue из Swift3 в objc, но возникла следующая ошибка. Невозможно инициализировать переменную типа '__strong dispatch_queue_t' (он же 'NSObject <OS_dispatch_queue> * __ strong') с значением типа 'OS_dispatch_queue * _Nonnull_ background_ display_queue_ _Nonnull_ background_ disp; = [SwiftClass Queue]; это статическая переменная DispatchQueue в swift
ideerge
DispatchQueue.main.asynchronously (DispatchQueue.main) {self.mapView.add (self.mapPolyline)} в Swift 3.0 я пытался с DispatchQueue.global (). Asynchronously (DispatchQueue.main) {self.mapView.add (self .mapPolyline)}, но оба показывают ту же ошибку, что и «значение типа dispathQuoue не имеет члена асинхронно»
Abirami Bala
1
из кода ОП, почему Apple фокусируется на использовании «com.swift3.imageQueue» . Я вижу, что этикетка состоит из 3 частей. Это почему? что означает каждая часть? Я не получаю форматирование
Милая
55

Компилируется под> = Swift 3 . Этот пример содержит большую часть синтаксиса, который нам нужен.

QoS - новый синтаксис качества обслуживания

weak self - чтобы нарушить удержание циклов

если личность недоступна, ничего не делай

async global utility queue- для сетевого запроса не ожидает результата, это параллельная очередь, блок (обычно) не ждет при запуске. Исключением для параллельной очереди может быть то, что, когда предел ее задачи был ранее достигнут, тогда очередь временно превращается в последовательную очередь и ожидает завершения какой-либо предыдущей задачи в этой очереди.

async main queue- для прикосновения к пользовательскому интерфейсу блок не ждет результата, а ждет своего слота в начале. Основная очередь является последовательной очередью.

Конечно, вам нужно добавить некоторые проверки ошибок к этому ...

DispatchQueue.global(qos: .utility).async { [weak self] () -> Void in

    guard let strongSelf = self else { return }

    strongSelf.flickrPhoto.loadLargeImage { loadedFlickrPhoto, error in

        if error != nil {
            print("error:\(error)")
        } else {
            DispatchQueue.main.async { () -> Void in
                activityIndicator.removeFromSuperview()
                strongSelf.imageView.image = strongSelf.flickrPhoto.largeImage
            }
        }
    }
}
t1ser
источник
6
При кодировании в Swift 3,
привыкните к сжатию
Спасибо за пример слабости!
imike
1
Это лучше , guardчто selfне nilна вершине, так что ни один из кодов не выполняется , если это nil, например, guard strongSelf = self else { return }.
Скотт Гарднер
@ t1 Не могли бы вы сказать мне, где я могу найти документацию для GCD, написанную с кодом в Swift 3? Я только нашел один написанный в Objective C . Кто-то здесь указывал мне на видео из WWDC, но я хочу прочитать официальную документацию с примерами в Swift 3, и я не могу ее найти.
bibscy
1
Не использовать .global(qos: .background)для ввода-вывода (сетевой запрос). Используйте .global(qos: .default)или .global(qos: .utility)вместо.
Педро Пауло Аморим
28

Скомпилировано в XCode 8, Swift 3 https://github.com/rpthomas/Jedisware

 @IBAction func tap(_ sender: AnyObject) {

    let thisEmail = "emailaddress.com"
    let thisPassword = "myPassword" 

    DispatchQueue.global(qos: .background).async {

        // Validate user input

        let result = self.validate(thisEmail, password: thisPassword)

        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if !result
            {
                self.displayFailureAlert()
            }

        }
    }

}
R Томас
источник
12

Поскольку на вопрос ОП уже был дан ответ, я просто хочу добавить некоторые соображения по поводу скорости:

Очень важно, какой приоритетный класс вы назначаете асинхронной функции в DispatchQueue.global .

Я не рекомендую запускать задачи с приоритетом потока .background, особенно на iPhone X, где кажется, что задача распределена по ядрам с низким энергопотреблением.

Вот некоторые реальные данные из вычислительно интенсивной функции, которая читает из файла XML (с буферизацией) и выполняет интерполяцию данных:

Имя устройства / .background / .utility / .default / .userInitiated / .userInteractive

  1. iPhone X: 18,7 с / 6,3 с / 1,8 с / 1,8 с / 1,8 с
  2. iPhone 7: 4,6 с / 3,1 с / 3,0 с / 2,8 с / 2,6 с
  3. iPhone 5s: 7,3 с / 6,1 с / 4,0 с / 4,0 с / 3,8 с

Обратите внимание, что набор данных не одинаков для всех устройств. Это самый большой на iPhone X и самый маленький на iPhone 5s.

Космин
источник
1
Отличная информация Помог мне
Моргз
1
@Myk Если пользователь инициировал и / или ожидает результатов, вы должны использовать .userInitiated или .userInteractive, чтобы любая другая операция была возвращена. В большинстве других случаев .default будет хорошим выбором.
Космин
6

Я сделал это, и это особенно важно, если вы хотите обновить свой пользовательский интерфейс, чтобы отображать новые данные без уведомления пользователя, как в UITableView или UIPickerView.

    DispatchQueue.main.async
 {
   /*Write your thread code here*/
 }
Асфанд Шаббир
источник
3
 DispatchQueue.main.async {
          self.collectionView?.reloadData() // Depends if you were populating a collection view or table view
    }


OperationQueue.main.addOperation {
    self.lblGenre.text = self.movGenre
}

// используем Очередь операций, если вам нужно заполнить объекты (метки, изображение, текстовое представление) на вашем контроллере вида

Фриц Джеральд Моран
источник
2
   let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT) //Swift 2 version

   let concurrentQueue = DispatchQueue(label:"com.swift3.imageQueue", attributes: .concurrent) //Swift 3 version

Я переработал ваш код в Xcode 8, Swift 3, и изменения помечены в отличие от вашей версии Swift 2.

gosborne3
источник
Это выглядит чище, чем я написал. Спасибо.
gosborne3
2

Свифт 3

Вы хотите вызвать некоторое замыкание в быстром коде, затем вы хотите изменить раскадровку, если вы измените любой тип, принадлежащий просмотру, ваше приложение потерпит крах

но вы хотите использовать метод отправки ваше приложение не будет падать

асинхронный метод

DispatchQueue.main.async 
{
 //Write code here                                   

}

метод синхронизации

DispatchQueue.main.sync 
{
     //Write code here                                  

}
Amul4608
источник
Я хочу использовать асинхронный метод во время вызова службы, мой код - DispatchQueue.main.async {let objstory1 = self.storyboard? .InstantiateViewController (withIdentifier: "HomeViewController") as! HomeViewController _ = self.navigationController? .PushViewController (objstory1, animated: false)}
Amul4608
1
Никогда не используйтеDispatchQueue.main.sync
trickster77777
Синхронизация вызовов в основной очереди, безусловно, вызовет проблемы.
Воин тофу
2
DispatchQueue.main.async(execute: {

// write code

})

Серийная очередь:

let serial = DispatchQueue(label: "Queuename")

serial.sync { 

 //Code Here

}

Параллельная очередь:

 let concurrent = DispatchQueue(label: "Queuename", attributes: .concurrent)

concurrent.sync {

 //Code Here
}
Хитеш Чаухан
источник
Это не создает очередь отправки, а просто помещает вас в основную очередь через один тик в цикле выполнения.
сборка завершена
1

Для Swift 3

   DispatchQueue.main.async {
        // Write your code here
    }
Иосиф Микко Маноза
источник
@ Мориц Я не могу не согласиться, к сожалению.
Орхан Алиханов
1
 let newQueue = DispatchQueue(label: "newname")
 newQueue.sync { 

 // your code

 }
глубоко
источник
1

Обновление для Swift 5

Serial Queue

let serialQueue = DispatchQueue.init(label: "serialQueue")
serialQueue.async {
    // code to execute
}

Параллельная очередь

let concurrentQueue = DispatchQueue.init(label: "concurrentQueue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)

concurrentQueue.async {
// code to execute
}

Из документации Apple :

параметры

метка

Метка строки, прикрепляемая к очереди, чтобы однозначно идентифицировать ее в инструментах отладки, таких как «Инструменты», «Образцы», «Стеки» и отчеты о сбоях. Поскольку приложения, библиотеки и платформы могут создавать свои собственные очереди отправки, рекомендуется стиль именования обратного DNS (com.example.myqueue). Этот параметр является необязательным и может иметь значение NULL.

QoS

Уровень качества обслуживания для связи с очередью. Это значение определяет приоритет, при котором система планирует задачи для выполнения. Список возможных значений см. В разделе DispatchQoS.QoSClass.

атрибуты

Атрибуты, связанные с очередью. Включите параллельный атрибут для создания очереди отправки, которая выполняет задачи одновременно. Если этот атрибут не указан, очередь отправки выполняет задачи последовательно.

autoreleaseFrequency

Частота автоматического высвобождения объектов, созданных блоками, запланированными для очереди. Список возможных значений см . В разделе DispatchQueue.AutoreleaseFrequency .

цель

Целевая очередь для выполнения блоков. Укажите DISPATCH_TARGET_QUEUE_DEFAULT, если вы хотите, чтобы система предоставила очередь, подходящую для текущего объекта.

Митра Сингам
источник
-3

теперь это просто:

let serialQueue = DispatchQueue(label: "my serial queue")

по умолчанию используется последовательный, чтобы получить параллелизм, используйте аргумент необязательных атрибутов .concurrent

tylernol
источник
Вам лучше обновить свой ответ, добавив seiralQueue.async {}. @tylemol
DawnSong
-3
DispatchQueue.main.async(execute: {
   // code
})
Хитеш Чаухан
источник
Спасибо за этот фрагмент кода, который может оказать некоторую немедленную помощь. Правильное объяснение значительно повысило бы его образовательную ценность, показав, почему это хорошее решение проблемы, и сделало бы его более полезным для будущих читателей с похожими, но не идентичными вопросами. Пожалуйста, отредактируйте свой ответ, чтобы добавить объяснение и указать, какие ограничения и предположения применяются.
Тоби Спейт
-4

Вы можете создать очередь отправки, используя этот код в Swift 3.0

DispatchQueue.main.async
 {
   /*Write your code here*/
 }

   /* or */

let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)                   
DispatchQueue.main.asyncAfter(deadline: delayTime)
{
  /*Write your code here*/
}
Нанд Парих
источник
1
Извините, это не создание очереди отправки, а доступ к основной очереди после одного шага через цикл выполнения.
сборка завершена