es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Swift Concurrency: Conformando una biblioteca de terceros al aislamiento de actores

Estoy en proceso de convertir algunas bases de código para usar Swift concurrency y me encuentro con algunos obstáculos en el camino.

El proyecto actual en el que estoy trabajando tiene algunas bibliotecas de terceros en las que se basa, y en una de esas bibliotecas, hay un protocolo de delegado que requiere que se devuelvan algunos valores de datos en sus métodos.

Aquí hay un ejemplo de los tipos de métodos de delegado en la biblioteca:

public protocol FooDelegate: AnyObject {
    func foo() -> CGFloat
}

Estoy intentando devolver algunos valores desde la implementación del protocolo de esta manera:

extension ViewController: FooDelegate {
    func foo() -> CGFloat { // <- No se puede cumplir el requisito del protocolo
        view.bounds.height
    }
}

Sin ninguna modificación, lo anterior está implícitamente aislado en el MainActor y no puede cumplir con el requisito del protocolo FooDelegate.

Una solución que he intentado fue marcar la implementación de la función con nonisolated:

extension ViewController: FooDelegate {
    nonisolated func foo() -> CGFloat {
        view.bounds.height // <- No se puede referenciar desde un contexto no aislado
    }
}

Pero esto no funcionó porque hace referencia a la vista del controlador de vista. Esto resulta en que la vista se referencia desde un contexto asíncrono no aislado. (También hay algunos otros problemas con esto, ya que cualquier valor que se pase a través de cualquiera de las funciones de delegado debe cumplir con Sendable para poder pasarse entre actores).

Mi pregunta es, ¿hay alguna manera de tomar una biblioteca de terceros y extenderla de alguna manera para que cumpla con un aislamiento de actor adecuado sin tener que modificar su código fuente?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, no hay una forma garantizada de tomar una biblioteca de terceros y hacer que se ajuste al aislamiento adecuado de actores sin modificar su código fuente. La biblioteca necesita actualizarse para funcionar con la concurrencia de Swift y los actores aislados, y esto requiere modificaciones en su código.

    Sin embargo, hay algunas alternativas que podrías considerar:

    1. Utilizar una clase envolvente: Podrías crear una clase envolvente alrededor del protocolo de delegado de la biblioteca, que se ajuste a los requisitos adecuados de aislamiento de actores. La clase envolvente llamaría entonces a los métodos de delegado de la biblioteca y devolvería los resultados de manera segura para los actores. De esta manera, podrías utilizar la biblioteca tal como está y sólo modificar la clase envolvente para que funcione con la concurrencia de Swift.
    2. Enviar una solicitud de extracción (pull request): Si la biblioteca es de código abierto, podrías enviar una solicitud de extracción para actualizarla y hacerla compatible con la concurrencia de Swift. Esto requeriría modificar el código fuente de la biblioteca, pero beneficiaría a toda la comunidad al actualizar la biblioteca y hacerla compatible con las prácticas modernas de Swift.

    3. Contactar a los desarrolladores de la biblioteca: Si la biblioteca no es de código abierto, podrías contactar a los desarrolladores y solicitarles que la actualicen para que funcione con la concurrencia de Swift. Esto puede o no ser factible dependiendo del estado de soporte y la hoja de ruta de desarrollo de la biblioteca.

    En cualquier caso, es importante asegurarse de que cualquier código que utilice la biblioteca se ajuste a los requisitos adecuados de aislamiento de actores para la seguridad y confiabilidad de tu aplicación.

Comments are closed.