Tengo muchas tareas asincrónicas que deben completarse antes de poder continuar, por lo que estoy usando un DispatchGroup. Sin embargo, puedo decir si una de las tareas falla temprano, y generalmente llamaría a un controlador de finalización.

Si dejo el alcance de la función llamando a un controlador de finalización, ¿qué sucede con DispatchGroup?

¿La memoria está asignada para siempre? ¿Es posible que si se abandona el permiso suficientes veces (tal vez debido a un error) que aún se pueda llamar al bloque de notificación?

Ejemplo:

func example(completion: @escaping (Bool) - Void) {
    let group = DispatchGroup()

    group.enter()
    asyncFunction1 {
        if result == false {
            completion(false)
        } else {
            group.leave()
        }
    }

    group.enter()
    asyncFunction2 { result in
        if result == true {
            group.leave()
        }
    }

    group.notify(queue: .main) {
        completion(true)
    }
}

En el ejemplo anterior tengo dos funciones asincrónicas. La primera función puede llamar a completion(false), y la segunda función solo llama a leave en caso de éxito. Si bien podría no ser el mejor ejemplo de código, estas condiciones son posibles. ¿Qué pasa con el bloque de notificación?

2
Michael Ozeryansky 17 sep. 2018 a las 09:47

3 respuestas

La mejor respuesta

De la fuente de Swift en GCD: https://github.com/apple/swift- corelibs-libdispatch / blob / master / src / semaphore.c

Parece que el bloque se asignará y nunca se liberará. Es decir, la memoria que retiene el bloque tampoco se liberará nunca.

4
Michael Ozeryansky 17 sep. 2018 a las 17:20

Me pregunto qué sucede cuando nunca se llama licencia. El hecho de que deba llamarse no significa que siempre se llame.

Bueno, no "nunca lo llames". Debe debe organizar su código para que leave sea llamado por cada ruta de salida posible. Si no puede, no use grupos de despacho.

Si es necesario, puede pasar el grupo de despacho al controlador de finalización para que pueda llamar a leave por usted. Pero de una forma u otra, llame al leave.

0
matt 17 sep. 2018 a las 17:08

El grupo de despacho debe ser notificado cada vez que un bloque de código ingresa al grupo, así como también cuando un bloque de código abandona el grupo.

Eso significa que se debe llamar a dispatchGroup.leave() independientemente del éxito o el fracaso de su función.

Cuando todos los bloques están terminados, se notifica al grupo de despacho.

1
zisoft 17 sep. 2018 a las 06:56