swift grand-central-dispatch swift3 xcode8

AutoreleaseFrequency en DispatchQueue en Swift 3 beta 5



grand-central-dispatch swift3 (2)

En Xcode 8 beta 5, el inicializador de DispatchQueue ha cambiado para aceptar argumentos separados para qos (calidad de servicio), atributos y frecuencia de liberación automática. Si bien no tuve ningún problema al convertir mi código para trabajar con el nuevo inicializador, no estoy seguro del significado de algunos de los atributos, en particular de la frecuencia de liberación automática.

Por ejemplo, en Xcode 8 beta 3 y Swift 3, pude crear un DispatchQueue serial como tal:

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

En Xcode 8 beta 5 y Swift 3:

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

Mis preguntas son:

  • En el nuevo DispatchQueue.Attributes, .serial ya no es un miembro. ¿Significa esto que la ausencia de .concurrent crea una cola en serie? Una prueba inicial que hice en Swift Playgrounds parece confirmar esto. ¿Alguien más puede confirmar?
  • Veo que DispatchQueue.AutoreleaseFrequency es un tipo nuevo con .inherit, .never y .workItem. ¿Qué significan estos? Hice algunas investigaciones sobre GCD y autoreleasing, pero no estoy muy familiarizado con el concepto de grupos de autorelease.

Considero que la respuesta dada por Mark es "subjetiva", como dijo, todavía no hay documentación oficial en los documentos. Sin embargo, puede encontrar la documentación oficial en el código, por lo que estoy dando lo que creo que debería ser la respuesta correcta, ya que se basa únicamente en lo que se encuentra en la documentación del código y no en la opinión. Aquí está:

DISPATCH_AUTORELEASE_FREQUENCY_INHERIT Las colas de envío con esta frecuencia de autorelease heredan el comportamiento de su cola de destino. Este es el comportamiento predeterminado para las colas creadas manualmente.

DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM Envíe colas con esta frecuencia de liberación automática, presione y abra un grupo de liberación automática alrededor de la ejecución de cada bloque que se envió de forma asíncrona.

DISPATCH_AUTORELEASE_FREQUENCY_NEVER Las colas de envío con esta frecuencia de liberación automática nunca configuran un conjunto de autorelease individual alrededor de la ejecución de un bloque que se envía de forma asíncrona. Este es el comportamiento de las colas simultáneas globales.


No pude encontrar ninguna documentación oficial de esos nuevos atributos (probablemente se esté trabajando en ella), pero dada la documentación existente de GCD y la lectura entre líneas, es bastante fácil intuir lo que se pretende aquí.

En el nuevo DispatchQueue.Attributes, .serial ya no es un miembro. ¿Significa esto que la ausencia de .concurrent crea una cola en serie? Una prueba inicial que hice en Swift Playgrounds parece confirmar esto. ¿Alguien más puede confirmar?

Sí. Una cola es en serie o concurrente. La mayoría de las colas que cree serán en serie, por lo que solo necesita configurarlas para que sean concurrentes si no desea el comportamiento predeterminado.

Veo que DispatchQueue.AutoreleaseFrequency es un tipo nuevo con .inherit, .never y .workItem. ¿Qué significan estos? Hice algunas investigaciones sobre GCD y autoreleasing, pero no estoy muy familiarizado con el concepto de grupos de autorelease.

Anteriormente, DispatchQueues hacía estallar sus grupos de autorelease en momentos no especificados (cuando el hilo quedaba inactivo). En la práctica, esto significó que usted creó un conjunto de autorelease para cada artículo de envío que envió, o que los objetos que se lanzaron de forma automática se mantendrían durante un período de tiempo impredecible.

El no determinismo no es una gran cosa (especialmente en una biblioteca de concurrencia), por lo que ahora le permiten especificar uno de los tres comportamientos:

.inherit: no está seguro, probablemente el comportamiento predeterminado previamente

.workItem: crea y drena un grupo de autorelease para cada elemento que se ejecuta

.never: GCD no administra grupos de autorelease por ti

De todos estos, probablemente solo querrá usar .workItem, porque limpiará sus objetos temporales cuando el elemento se complete. Las otras opciones son presumiblemente para el código de buggy que depende del comportamiento anterior, o para ese usuario raro que realmente quiere administrar estas cosas por sí mismos.

En realidad, pensándolo un poco más, si está enviando elementos de trabajo que son solo de Swift (no llaman a ningún código de Objective-C), entonces probablemente nunca sea seguro y correcto. Dado que cualquiera o todas las clases de la biblioteca estándar de Swift pueden llamar a algún código de Objective-C, probablemente querrá limitar esto a los cálculos que residen completamente dentro de su propio código de Swift.