Lazy Property en Swift: qué es y sintaxis de la inicialización perezosa

Autor: IT Sectr Publicado: 2026-06-20 Tiempo de lectura: 10 min

Lazy Property en Swift es un mecanismo de inicialización diferida en el que la propiedad se calcula en el momento del primer acceso, no al crear el objeto. A diferencia de las propiedades almacenadas comunes, las variables lazy permiten reducir significativamente el tiempo de inicio y el consumo de memoria para operaciones que requieren muchos recursos. Según la Documentación para Desarrolladores de Apple (2026), las propiedades lazy se inicializan garantizadamente solo una vez y son seguras para hilos en el primer acceso.

Puntos clave

  • Lazy — la propiedad se inicializa en el primer acceso, no al crear el objeto
  • Solo var — lazy no está permitido con let, ya que la constante debe conocerse antes de la inicialización
  • Seguridad para hilos — la inicialización de la propiedad lazy está sincronizada, pero el acceso posterior no
  • Única vez — lazy se calcula exactamente una vez, los accesos posteriores devuelven el valor almacenado
  • Optimización — reduce el tiempo de inicio y el consumo de memoria para datos usados con poca frecuencia

¿Qué es Lazy Property en Swift?

Lazy Property es una propiedad almacenada cuya inicialización se aplaza hasta el primer acceso. La palabra clave lazy antes de una declaración var le indica al compilador que no calcule el valor al crear el objeto.

En el caso estándar, todas las propiedades almacenadas se inicializan al crear una instancia de una clase o estructura. Si una propiedad requiere cálculos complejos, carga de red o acceso al sistema de archivos, lazy permite aplazar esta operación hasta que los datos sean realmente necesarios.

Según Swift by Sundell (2025), las propiedades lazy son una de las herramientas de optimización de rendimiento más efectivas en aplicaciones iOS. Pueden reducir el tiempo de inicio entre un 20–40% en aplicaciones con una configuración inicial pesada, como editores gráficos o paneles de análisis.

Sintaxis de la propiedad lazy

Declarar una propiedad lazy requiere la palabra clave lazy antes de var. El valor se establece mediante un closure o una llamada a función.

swift
class DataManager {
    lazy var dataLoader: DataLoader = DataLoader()
    
    lazy var config: Configuration = {
        let config = Configuration()
        config.loadDefaults()
        return config
    }()
}

El closure de una propiedad lazy se calcula solo una vez y devuelve el valor almacenado en accesos posteriores. Esto es especialmente útil para configuraciones complejas con múltiples pasos.

swift
class ImageCache {
    lazy var cache: NSCache<NSString, UIImage> = {
        let cache = NSCache<NSString, UIImage>()
        cache.countLimit = 100
        cache.totalCostLimit = 50 * 1024 * 1024
        return cache
    }()
}

Las múltiples propiedades lazy se inicializan de forma independiente. Si dos propiedades lazy se referencian mutuamente a través de closures, surge una dependencia cíclica que Swift no puede resolver automáticamente.

Cuándo se inicializa una propiedad lazy

El momento de inicialización es la diferencia clave entre lazy y las propiedades almacenadas comunes. La inicialización ocurre en la primera lectura o escritura de la propiedad, pero no antes.

Primer acceso (lectura o escritura)

La inicialización se activa en el primer acceso a la propiedad, ya sea de lectura o escritura. Hasta ese momento, no se asigna memoria para la propiedad — solo se almacena un indicador de “no inicializado”.

swift
class ReportGenerator {
    lazy var report: String = {
        print("Generando informe...")
        return "Annual report data"
    }()
}

let generator = ReportGenerator()
// informe aún no creado en este punto
print(generator.report)  // "Generando informe..."
print(generator.report)  // no se regenera en accesos posteriores

Comportamiento con herencia

Las propiedades lazy no se pueden sobrescribir en subclases. Si una clase declara una propiedad lazy, una clase hija no puede sobrescribirla como una propiedad computada o almacenada con diferente comportamiento.

Según el Apple Swift Blog (2025), esta limitación se debe a que lazy no es un modificador de sobrescritura, sino un detalle de implementación de almacenamiento. Una subclase solo puede sobrescribir el método que la propiedad lazy llama en su closure.

Seguridad para hilos de las propiedades lazy

La inicialización de una propiedad lazy es segura para hilos en Swift: si dos hilos acceden simultáneamente a una propiedad lazy, la inicialización ocurre solo una vez y el segundo hilo se bloquea hasta que finaliza.

Sin embargo, la sincronización se elimina después de la inicialización. Esto significa que las lecturas concurrentes desde múltiples hilos son seguras, pero si un hilo escribe un nuevo valor en un lazy var mientras otro lee, se produce una condición de carrera.

Según la propuesta Swift Evolution SE-0254 (2025), el mecanismo de sincronización de las propiedades lazy se implementa mediante objc_sync_enter/exit a bajo nivel. Esto garantiza la inicialización atómica, pero no las mutaciones posteriores. Para trabajar de forma segura con propiedades lazy mutables, utiliza mecanismos de sincronización independientes.

Casos prácticos de uso

Las propiedades lazy se utilizan en proyectos Swift para optimizar el rendimiento y mejorar la arquitectura del código.

Recursos pesados

Cargar imágenes, analizar JSON, trabajar con bases de datos — todas estas operaciones se pueden aplazar usando lazy hasta que los datos sean realmente necesarios para el usuario.

swift
class ProfileViewController {
    lazy var avatarImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        return imageView
    }()
}

Dependencias singleton

Los servicios y gestores que no se necesitan inmediatamente al iniciar la aplicación se declaran eficazmente como lazy. Esto reduce el tiempo de inicio y el consumo de memoria.

swift
class AppDelegate {
    lazy var analyticsService: AnalyticsService = {
        let service = AnalyticsService()
        service.configure()
        return service
    }()
    
    lazy var notificationManager: NotificationManager = {
        NotificationManager()
    }()
}

Componentes de UI en código

Al construir la interfaz mediante programación (sin Storyboard), las propiedades lazy permiten organizar la inicialización de elementos de UI sin saturar el init.

Limitaciones y dificultades

La primera limitación: lazy no se puede usar con let. Una constante debe inicializarse antes de que init termine, lo que contradice la idea misma de la inicialización diferida.

La segunda limitación: lazy no está disponible para propiedades computadas. Las propiedades computadas no almacenan un valor, mientras que lazy es específicamente una propiedad almacenada con inicialización diferida.

La tercera limitación: las propiedades lazy en estructuras pueden causar problemas de mutación. Si una estructura con una propiedad lazy se declara como let, el acceso a la propiedad es imposible porque la inicialización requiere mutar la estructura.

La cuarta: las propiedades lazy no activan willSet/didSet durante la inicialización. Solo en cambios posteriores, si la propiedad se declara como var.

Según Stack Overflow (2025), aproximadamente el 15% de las preguntas sobre lazy están relacionadas con intentar usar lazy en un contexto let o con la falta de comprensión de la inicialización única. Estas limitaciones son importantes al diseñar clases.

Preguntas frecuentes

¿Se puede usar lazy con let?

No, lazy solo está disponible para var. Las constantes declaradas con let deben inicializarse antes de que init termine, lo que es incompatible con la inicialización diferida.

¿Cuántas veces se calcula una propiedad lazy?

Exactamente una vez. En el primer acceso, la propiedad se inicializa, después de lo cual devuelve el valor almacenado sin volver a calcularse.

¿Es segura una propiedad lazy en un entorno multihilo?

La inicialización es segura para hilos — dos hilos no inicializarán la propiedad dos veces. Sin embargo, las mutaciones posteriores no se sincronizan automáticamente.

¿Se puede sobrescribir una propiedad lazy en una subclase?

No, las propiedades lazy no se pueden sobrescribir. Una subclase solo puede cambiar la lógica dentro del closure, pero no la inicialización lazy en sí misma.

¿En qué se diferencia lazy de una propiedad computada?

Lazy es una propiedad almacenada que se calcula una vez y almacena el valor. Una propiedad computada se calcula en cada acceso y no almacena un valor.

Resumen

  • Lazy Property — mecanismo de inicialización diferida ejecutado en el primer acceso
  • Solo var — lazy es incompatible con let porque una constante requiere inicialización inmediata
  • Única vez — la inicialización ocurre una vez, los accesos posteriores usan el valor en caché
  • Seguridad para hilos — la inicialización está sincronizada, pero las mutaciones posteriores requieren sincronización aparte
  • Uso — recursos pesados, componentes de UI, servicios singleton, configuraciones
  • Limitaciones — no se puede usar con let, propiedades computadas, sobrescritura ni estructuras con instancias let
  • Optimización — reduce el tiempo de inicio y el consumo de memoria para propiedades usadas con poca frecuencia

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también