Llamar a una función asincrónica de Swift en el actor principal desde un contexto sincrónico.
Estoy tratando de entender por qué el siguiente fragmento de código genera una afirmación. Lo que estoy tratando de hacer es llamar a asyncFunc()
en el hilo principal/actor principal desde el sitio de llamada. No quiero decorar asyncFunc con @MainActor
ya que quiero que la función sea independiente del hilo.
func asyncFunc() async -> String? {
dispatchPrecondition(condition: .onQueue(.main))
return "abc"
}
func callSite() {
Task { @MainActor in
await asyncFunc()
}
}
Mi entendimiento era que Task { @MainActor ...}
ejecutaría todo el código siguiente en MainActor/hilo principal.
davy.ai
La razón por la que el fragmento de código anterior genera una afirmación es debido al uso de
dispatchPrecondition
dentro de la funciónasyncFunc()
. La funcióndispatchPrecondition
verifica el hilo actual en el que se está ejecutando la función y si no es en el hilo especificado, la función genera una afirmación en tiempo de ejecución.En este caso, dado que
asyncFunc()
tienedispatchPrecondition
con la condición.onQueue(.main)
, se espera que se ejecute en el hilo principal. Sin embargo, cuando se llama acallSite()
, el decoradorTask
con@MainActor
solo marca el cierre como si se estuviera ejecutando en elMainActor
, y no necesariamente en el hilo principal.Para solucionar esto, puedes envolver la llamada
await asyncFunc()
dentro de un bloquewithCheckedContinuation
, lo cual permitirá que la función sea independiente del hilo. Aquí te mostramos cómo puedes modificar el código para corregir la afirmación:Con las modificaciones anteriores, el código dentro de
Task
ahora está envuelto con un bloquewithCheckedContinuation
que le permite ser independiente del hilo. Específicamente, el cierre dentro deDispatchQueue.main.async {...}
garantiza que la funciónasyncFunc()
se ejecute en el hilo principal mientras permite queTask
continúe ejecutándose en elMainActor
.