AutoreleaseFrequency на DispatchQueue в Swift 3

В Xcode 8 beta 5 инициализатор для DispatchQueue изменился, чтобы принять отдельные аргументы для qos (качество обслуживания), атрибутов и частоты автозапуска. В то время как у меня не было никаких проблем с преобразованием моего кода для работы с новым инициализатором, я не уверен в значении некоторых атрибутов, в частности частоты авторекламы.

Например, в Xcode 8 beta 3 и Swift 3 мне удалось создать серийный DispatchQueue как таковой:

let serialQueue = DispatchQueue(label: "Concurrent Map", attributes: [.serial, .qosBackground], target: nil)

В Xcode 8 beta 5 и Swift 3:

let serialQueue = DispatchQueue(label: "Concurrent Map", qos: .background, attributes: [], autoreleaseFrequency: .inherit, target: nil)

Мои вопросы:

  • В новом DispatchQueue.Attributes,.serial больше не является членом. Означает ли это, что отсутствие .concurrent создает последовательную очередь. Первоначальный тест, который я сделал в Swift Playgrounds, похоже, подтверждает это. Может ли кто-нибудь еще подтвердить?
  • Я вижу, что DispatchQueue.AutoreleaseFrequency - это новый тип с .inherit,.never и .workItem. Что это значит? Я провел некоторое исследование GCD и autoreleasing, но я не очень хорошо знаком с концепцией пулов авторефератов.

Ответы

Ответ 1

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

В новом DispatchQueue.Attributes,.serial больше не является членом. Означает ли это, что отсутствие .concurrent создает последовательную очередь. Первоначальный тест, который я сделал в Swift Playgrounds, похоже, подтверждает это. Можно кто-нибудь еще подтверждает?

Да. Очередь является последовательной или параллельной. Большинство создаваемых вами очередей будут серийными, поэтому вам нужно установить их одновременно, если вы не хотите поведения по умолчанию.

Я вижу, что DispatchQueue.AutoreleaseFrequency - это новый тип с .inherit,.everever и .workItem. Что это значит? Я сделал исследования GCD и автореализаций, но я не очень хорошо знаком с концепция пулов авторефератов.

Ранее DispatchQueues появлялся в пулах автозаполнения в неопределенные времена (когда поток стал неактивным). На практике это означало, что вы либо создали пул авторесурсов для каждого отправленного вами элемента отправки, либо ваши объекты с автореализацией будут зависать в течение непредсказуемого времени.

Недетерминизм - это не очень хорошо (особенно в библиотеке concurrency!), поэтому теперь они позволяют указать одно из трех типов поведения:

.inherit: Не уверен, возможно, поведение по умолчанию

.workItem: создать и слить пул автозапуска для каждого элемента, который будет выполнен

.never: GCD не управляет пулами автозапуска для вас

Из всего этого вы, скорее всего, захотите использовать .workItem, потому что он очистит ваши временные объекты, когда элемент будет завершен. Другие варианты, по-видимому, предназначены для любого багги-кода, который зависит от старого поведения, или для этого редкого пользователя, который действительно хочет сам управлять этим материалом.


На самом деле, думая об этом немного больше, если вы отправляете рабочие элементы, которые являются Swift-only (они не звонят в какой-либо код Objective-C), то никогда не будет, вероятно, безопасным и правильным. Учитывая, что любые/все классы стандартной библиотеки Swift могут вызывать код Objective-C, вы, вероятно, захотите ограничить его вычислениями, которые полностью находятся внутри вашего собственного кода Swift.

Ответ 2

Я нахожу ответ, данный Марк "субъективным", по его словам, официальной документации в документах пока нет. Однако вы можете найти официальную документацию в коде, поэтому я даю то, что, по моему мнению, должен быть правильным ответом, поскольку он основан исключительно на том, что содержится в документации по коду, а не на мнении. Вот он:

DISPATCH_AUTORELEASE_FREQUENCY_INHERIT Диспетчерские очереди с этой частотой автозапуска наследуют поведение от их целевой очереди. Это поведение по умолчанию для создаваемых вручную очередей.

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

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