Lazy Property em Swift: o que é e sintaxe da inicialização preguiçosa

Autor: IT Sectr Publicado: 2026-06-20 Tempo de leitura: 10 min

Lazy Property em Swift é um mecanismo de inicialização adiada no qual a propriedade é calculada no momento do primeiro acesso, e não quando o objeto é criado. Ao contrário das propriedades armazenadas comuns, variáveis lazy permitem reduzir significativamente o tempo de inicialização e o consumo de memória para operações que exigem muitos recursos. De acordo com a Documentação para Desenvolvedores da Apple (2026), as propriedades lazy são garantidamente inicializadas apenas uma vez e são seguras para threads no primeiro acesso.

Pontos principais

  • Lazy — a propriedade é inicializada no primeiro acesso, não ao criar o objeto
  • Apenas var — lazy não é permitido com let, pois a constante deve ser conhecida antes da inicialização
  • Segurança de threads — a inicialização da propriedade lazy é sincronizada, mas o acesso subsequente não
  • Única vez — lazy é calculado exatamente uma vez, acessos posteriores retornam o valor armazenado
  • Otimização — reduz o tempo de inicialização e o consumo de memória para dados raramente usados

O que é Lazy Property em Swift?

Lazy Property é uma propriedade armazenada cuja inicialização é adiada até o primeiro acesso. A palavra-chave lazy antes de uma declaração var instrui o compilador a não calcular o valor quando o objeto é criado.

No caso padrão, todas as propriedades armazenadas são inicializadas ao criar uma instância de uma classe ou estrutura. Se uma propriedade requer cálculos complexos, carregamento de rede ou operações de sistema de arquivos, lazy permite adiar esta operação até que os dados sejam realmente necessários.

De acordo com Swift by Sundell (2025), as propriedades lazy são uma das ferramentas de otimização de desempenho mais eficazes em aplicativos iOS. Elas podem reduzir o tempo de inicialização em 20–40% em aplicativos com configuração inicial pesada, como editores gráficos ou painéis de análise.

Sintaxe da propriedade lazy

Declarar uma propriedade lazy requer a palavra-chave lazy antes de var. O valor é definido através de um closure ou chamada de função.

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

O closure de uma propriedade lazy é calculado apenas uma vez e retorna o valor armazenado em acessos subsequentes. Isso é especialmente conveniente para configurações complexas com múltiplas etapas.

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

Múltiplas propriedades lazy são inicializadas independentemente. Se duas propriedades lazy se referenciam mutuamente através de closures, surge uma dependência cíclica que o Swift não pode resolver automaticamente.

Quando uma propriedade lazy é inicializada

O momento da inicialização é a diferença chave entre lazy e propriedades armazenadas comuns. A inicialização ocorre na primeira leitura ou escrita da propriedade, mas não antes.

Primeiro acesso (leitura ou escrita)

A inicialização é acionada no primeiro acesso à propriedade, seja leitura ou escrita. Até esse momento, nenhuma memória é alocada para a propriedade — apenas um sinalizador “não inicializado” é armazenado.

swift
class ReportGenerator {
    lazy var report: String = {
        print("Gerando relatório...")
        return "Annual report data"
    }()
}

let generator = ReportGenerator()
// relatório ainda não criado neste ponto
print(generator.report)  // "Gerando relatório..."
print(generator.report)  // não regenerado em acessos subsequentes

Comportamento com herança

Propriedades lazy não podem ser sobrescritas em subclasses. Se uma classe declara uma propriedade lazy, uma classe filha não pode sobrescrevê-la como uma propriedade computada ou armazenada com comportamento diferente.

De acordo com o Apple Swift Blog (2025), esta limitação ocorre porque lazy não é um modificador de sobrescrita, mas um detalhe de implementação de armazenamento. Uma subclasse só pode sobrescrever o método que a propriedade lazy chama em seu closure.

Segurança de threads das propriedades lazy

A inicialização de uma propriedade lazy é segura para threads em Swift: se duas threads acessam uma propriedade lazy simultaneamente, a inicialização ocorre apenas uma vez e a segunda thread é bloqueada até que termine.

No entanto, a sincronização é removida após a inicialização. Isso significa que leituras concorrentes de múltiplas threads são seguras, mas se uma thread escreve um novo valor em um lazy var enquanto outra lê, ocorre uma condição de corrida.

De acordo com a proposta Swift Evolution SE-0254 (2025), o mecanismo de sincronização para propriedades lazy é implementado através de objc_sync_enter/exit em baixo nível. Isso garante inicialização atômica, mas não mutações subsequentes. Para trabalhar de forma segura com propriedades lazy mutáveis, use mecanismos de sincronização separados.

Casos de uso práticos

Propriedades lazy são usadas em projetos Swift para otimizar o desempenho e melhorar a arquitetura do código.

Recursos pesados

Carregar imagens, analisar JSON, trabalhar com bancos de dados — todas essas operações podem ser adiadas usando lazy até que os dados sejam realmente necessários pelo usuário.

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

Dependências singleton

Serviços e gerenciadores que não são necessários imediatamente na inicialização do aplicativo são efetivamente declarados como lazy. Isso reduz o tempo de inicialização e o consumo de memória.

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

Componentes de UI em código

Ao construir a interface programaticamente (sem Storyboard), propriedades lazy permitem organizar a inicialização de elementos de UI sem poluir o init.

Limitações e armadilhas

A primeira limitação: lazy não pode ser usado com let. Uma constante deve ser inicializada antes do init terminar, o que contradiz a própria ideia de inicialização adiada.

A segunda limitação: lazy não está disponível para propriedades computadas. Propriedades computadas não armazenam um valor, enquanto lazy é especificamente uma propriedade armazenada com inicialização adiada.

A terceira limitação: propriedades lazy em structs podem causar problemas de mutação. Se uma struct com uma propriedade lazy é declarada como let, o acesso à propriedade é impossível porque a inicialização requer a mutação da struct.

A quarta: propriedades lazy não acionam willSet/didSet durante a inicialização. Apenas em alterações subsequentes, se a propriedade for declarada como var.

De acordo com o Stack Overflow (2025), cerca de 15% das perguntas sobre lazy estão relacionadas a tentativas de usar lazy em um contexto let ou à falta de compreensão da inicialização única. Estas limitações são importantes ao projetar classes.

Perguntas frequentes

Pode-se usar lazy com let?

Não, lazy está disponível apenas para var. Constantes declaradas com let devem ser inicializadas antes do init terminar, o que é incompatível com a inicialização adiada.

Quantas vezes uma propriedade lazy é calculada?

Exatamente uma vez. No primeiro acesso, a propriedade é inicializada, após o que retorna o valor armazenado sem recalcular.

Uma propriedade lazy é segura em ambiente multithread?

A inicialização é segura para threads — duas threads não inicializarão a propriedade duas vezes. No entanto, mutações subsequentes não são sincronizadas automaticamente.

Uma propriedade lazy pode ser sobrescrita em uma subclasse?

Não, propriedades lazy não podem ser sobrescritas. Uma subclasse só pode alterar a lógica dentro do closure, mas não a inicialização lazy em si.

Como lazy difere de propriedade computada?

Lazy é uma propriedade armazenada que é calculada uma vez e armazena o valor. Uma propriedade computada é calculada em cada acesso e não armazena valor.

Resumo

  • Lazy Property — mecanismo de inicialização adiada executado no primeiro acesso
  • Apenas var — lazy é incompatível com let porque uma constante requer inicialização imediata
  • Única vez — a inicialização ocorre uma vez, acessos posteriores usam o valor em cache
  • Segurança de threads — a inicialização é sincronizada, mas mutações após a inicialização requerem sincronização separada
  • Uso — recursos pesados, componentes de UI, serviços singleton, configurações
  • Limitações — não pode ser usado com let, propriedades computadas, sobrescrita ou structs com instâncias let
  • Otimização — reduz o tempo de inicialização e o consumo de memória para propriedades raramente usadas

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também