El patrón de delegación (delegation) es uno de los clave en el ecosistema de Swift, utilizado ampliamente para transferir la responsabilidad de gestionar eventos entre objetos. La delegación permite a una clase delegar una parte de su comportamiento a otro objeto (delegado), que generalmente se define a través de un protocolo.
protocol DataUpdateDelegate: AnyObject { func didUpdateData(_ data: String) } class DataProvider { weak var delegate: DataUpdateDelegate? func updateData() { // ... lógica de actualización de datos delegate?.didUpdateData("Nuevos datos") } } class ViewController: UIViewController, DataUpdateDelegate { func didUpdateData(_ data: String) { print("Los datos se han actualizado: \(data)") } }
weak (o unowned), para evitar ciclos de retención.AnyObject, para permitir referencias weak.¿Cómo implementan la delegación si su delegado es un tipo de valor (por ejemplo, struct)?
Respuesta:
En Swift, los delegados deben ser tipos de referencia (class o AnyObject), porque solo un tipo de referencia permite la referencia weak. Un struct o enum no puede actuar como delegado, de lo contrario, surgirán problemas: el compilador no permitirá usar una propiedad weak, y una referencia fuerte causará un ciclo de retención.
// ¡Error! No se puede declarar un delegado como struct: el compilador no permitirá hacerlo weak protocol StructDelegate { ... } struct MyStructDelegate: StructDelegate { ... } weak var delegate: StructDelegate? // Error
Historia
En un proyecto, olvidaron marcar la propiedad del delegado como weak. Como resultado, surgió un ciclo de retención entre la vista y el delegado, la aplicación comenzó a "inflarse" en memoria y se bloqueaba después de media hora de uso.
Historia
El delegado se implementó a través de un tipo de valor (struct), en lugar de una clase. El IBOutlet que debía ser el delegado no recibía notificaciones: no había conexión en absoluto. El problema se descubrió solo después de analizar los registros y depurar.
Historia
En un proyecto, el protocolo del delegado no heredó de AnyObject, y la propiedad del delegado se declaró como weak var. Esto llevó a un error de compilación que al equipo le tomó tiempo entender y corregir.