@ObservedObject: o que é, como funciona e exemplos

Autor: IT Sectr Publicado: 2026-06-19 Tempo de leitura: 7 min

@ObservedObject é um Property Wrapper no SwiftUI para observar uma instância de ObservableObject passada externamente. Ao contrário de @StateObject, @ObservedObject não cria um objeto — ele se inscreve nas mudanças de um já existente. De acordo com a Documentação para Desenvolvedores Apple (2025), @ObservedObject é usado em view filhas que precisam rastrear dados pertencentes ao pai. @ObservedObject fornece uma conexão reativa sem gerenciar o ciclo de vida do objeto.

Principais pontos

  • @ObservedObject — Property Wrapper para observar ObservableObject sem propriedade
  • Sem criação — o objeto é passado da view pai ou do ambiente
  • @Published — propriedades dentro de ObservableObject cujas mudanças o SwiftUI rastreia
  • Re-renderização — quando uma propriedade @Published muda, o SwiftUI atualiza todas as views inscritas
  • Não confundir com @StateObject — @ObservedObject não garante uma única instância

O que é @ObservedObject no SwiftUI?

@ObservedObject é um Property Wrapper que inscreve uma view nas mudanças de um ObservableObject. ObservableObject é um protocolo do framework Combine que requer a implementação de um publisher objectWillChange. Quando qualquer propriedade marcada com @Published muda dentro do ObservedObject, o publisher envia um sinal e o SwiftUI re-renderiza todas as views inscritas através de @ObservedObject.

A principal característica do @ObservedObject é a ausência de propriedade. A view não é responsável por criar ou destruir o objeto. O objeto é criado na view pai (via @StateObject) ou injetado através de @EnvironmentObject. A view filha apenas observa as mudanças e recebe atualizações. Se o objeto for substituído no pai, @ObservedObject muda para a nova instância.

@ObservedObject é adequado para cenários de compartilhamento de dados: modelo de usuário, configurações comuns, estado de conexão com o servidor. Quando várias views em diferentes níveis hierárquicos precisam exibir os mesmos dados, @ObservedObject em cada view cria assinaturas independentes mas consistentes para uma única fonte.

@ObservedObject vs @StateObject: diferenças principais

A diferença entre @ObservedObject e @StateObject é um dos tópicos mais comuns em entrevistas sobre SwiftUI. A regra principal: @StateObject cria e possui o objeto, @ObservedObject observa um já existente. Violar essa regra leva à perda inesperada de dados ou inicialização dupla.

Característica@StateObject@ObservedObject
Criação do objetoSim, na inicialização da viewNão, recebe um já pronto
PropriedadeView atualComponente pai
Instância únicaSim, por todo o ciclo de vidaNão, pode ser substituída
Recriação ao renderizarNão, persisteDepende do pai
Onde usarView raiz proprietáriaViews filhas

@StateObject garante que o objeto é criado uma vez e sobrevive a inicializações repetidas da estrutura da view. @ObservedObject recebe o objeto externamente e é recriado a cada inicialização da estrutura pai. Se o pai usa @StateObject para o objeto, as views filhas podem usar @ObservedObject com segurança — o objeto será único em toda a hierarquia.

Como @ObservedObject rastreia mudanças

O mecanismo de rastreamento do @ObservedObject é baseado no Combine e no protocolo ObservableObject. Durante a inicialização, o SwiftUI chama o publisher objectWillChange — o objeto deve emitir um sinal antes de alterar uma propriedade @Published. O Combine passa o sinal para o grafo de dependências do SwiftUI, que marca todas as views dependentes como precisando de atualização. Isso acontece sincronamente antes do valor ser alterado.

swift
class WeatherService: ObservableObject {
    @Published var temperature: Double = 22.0
    @Published var city: String = "Moscow"
}

struct WeatherView: View {
    @ObservedObject var weather: WeatherService

    var body: some View {
        VStack {
            Text("\(weather.city)")
            Text("\(weather.temperature)°C")
        }
    }
}

No exemplo WeatherService é um ObservableObject com duas propriedades @Published. WeatherView declara @ObservedObject var weather: WeatherService, recebendo a instância do pai. Quando temperature muda, objectWillChange é disparado antes de definir o novo valor, o SwiftUI re-renderiza WeatherView e a temperatura atual é exibida. A assinatura é gerenciada automaticamente pelo SwiftUI — o desenvolvedor não precisa chamar sink ou dispose.

Padrões de uso do @ObservedObject

O primeiro padrão é passar um modelo pelo inicializador. O pai cria um ObservableObject via @StateObject e o passa para as views filhas como @ObservedObject. Esta é uma transferência hierárquica padrão de dados onde a view raiz gerencia o ciclo de vida do modelo e todos os componentes aninhados se inscrevem nas mudanças.

O segundo padrão é EnvironmentObject, uma versão global do @ObservedObject através do ambiente SwiftUI. O objeto é injetado no nível da cena ou view raiz e fica automaticamente disponível para todos os componentes filhos sem passagem explícita por inicializadores. Dentro da view filha, @EnvironmentObject funciona de forma similar ao @ObservedObject mas recebe o objeto do ambiente.

O terceiro padrão é a composição de múltiplos ObservableObject. Em aplicações complexas, uma view pode observar vários objetos: @ObservedObject var user: UserService, @ObservedObject var network: NetworkMonitor. Isso separa responsabilidades entre serviços e mantém a testabilidade de cada componente.

swift
struct DashboardView: View {
    @ObservedObject var user: UserViewModel
    @ObservedObject var network: NetworkMonitor

    var body: some View {
        VStack {
            Text("Welcome, \(user.name)")
            HStack {
                Circle()
                    .fill(network.isConnected ? Color.green : Color.red)
                    .frame(width: 10, height: 10)
            }
        }
    }
}

DashboardView observa UserViewModel e NetworkMonitor. Cada objeto lida com seu próprio domínio de dados e notifica a view independentemente sobre mudanças. Se a rede desconectar, NetworkMonitor altera isConnected e o SwiftUI re-renderiza DashboardView, atualizando a cor do indicador. A composição de ObservableObject é a forma preferida de organizar dados em aplicações SwiftUI.

@Published: a ligação entre ObservableObject e SwiftUI

@Published é um Property Wrapper do Combine que adiciona automaticamente um publisher a uma propriedade dentro de ObservableObject. Quando uma propriedade @Published muda, o Combine gera um evento através do publisher objectWillChange. O SwiftUI se inscreve neste publisher ao usar @ObservedObject ou @StateObject e re-renderiza a view a cada novo valor.

@Published suporta todos os tipos, incluindo opcionais, coleções e estruturas personalizadas. No entanto, para coleções (arrays, dicionários), o SwiftUI rastreia apenas a substituição da referência, não a mutação do conteúdo. Para detectar adição ou remoção de elementos, é necessário reatribuir a coleção inteira ou usar ObservableObject com objectWillChange.send() manual.

Um detalhe importante: @Published deve ser usado apenas dentro de uma classe que implementa ObservableObject. Usar @Published fora de ObservableObject causará um erro de compilação. Além disso, @Published não pode ser aplicado a propriedades de inicialização preguiçosa (lazy var) ou propriedades computadas.

Erros comuns com @ObservedObject

O erro mais crítico é usar @ObservedObject para criar um objeto. Se você escrever @ObservedObject var model = UserViewModel() na view pai, cada renderização criará uma nova instância de UserViewModel. Os dados serão perdidos e as assinaturas @Published serão recriadas. Use sempre @StateObject para criação e @ObservedObject apenas para receber um objeto já pronto.

O segundo erro é modificar propriedades @Published fora da thread principal. ObservableObject usa Combine, que requer o envio de mudanças na thread principal (main actor). Se você alterar @Published em uma fila de fundo, o SwiftUI pode re-renderizar a view em um momento inadequado, causando condições de corrida. Use DispatchQueue.main.async ou @MainActor para atualizações.

O terceiro problema são as atualizações cíclicas. Se uma mudança @Published desencadeia efeitos colaterais que novamente alteram @Published, ocorre um loop infinito de re-renderização. A solução: usar flags de proteção (isUpdating) ou separar a lógica em diferentes ObservableObject com limites de responsabilidade claros.

Perguntas frequentes

@ObservedObject pode ser opcional?

Sim, o SwiftUI suporta @ObservedObject var model: UserViewModel?. No entanto, a view não será inscrita em mudanças enquanto o objeto for nil. Quando um valor é atribuído, a assinatura é ativada automaticamente.

Qual a diferença entre @ObservedObject e @EnvironmentObject?

@ObservedObject recebe o objeto através do inicializador, @EnvironmentObject através do ambiente SwiftUI. @EnvironmentObject não requer passagem explícita por construtores, mas o objeto deve ser injetado no nível superior da hierarquia.

Como notificar manualmente o SwiftUI sobre uma mudança no ObservableObject?

Chame objectWillChange.send() antes de alterar a propriedade. Isso é útil quando @Published não é adequado (por exemplo, para propriedades computadas ou operações com coleções onde você precisa relatar a mudança antes da mutação).

Por que @ObservedObject não re-renderiza a view ao mudar dentro de um array?

@ObservedObject e @Published rastreiam a substituição da referência, não a mutação do conteúdo da coleção. Para acionar uma re-renderização, você precisa reatribuir o array: items.append(newItem) → items = items ou usar objectWillChange.send() antes da mutação.

Pode-se usar @ObservedObject em uma struct que não implementa View?

Não, @ObservedObject é um Property Wrapper do SwiftUI disponível apenas dentro de tipos que implementam o protocolo View. Para structs comuns, use Combine diretamente com ObservableObjectPublisher.

Resumo

  • @ObservedObject — Property Wrapper para observar ObservableObject sem propriedade
  • @StateObject — cria o objeto, @ObservedObject — observa um existente
  • @Published — publisher automático para propriedades ObservableObject
  • Assinatura — SwiftUI gerencia automaticamente a assinatura Combine ao usar @ObservedObject
  • Composição — uma view pode observar vários ObservableObject simultaneamente
  • Main actor — propriedades @Published devem ser alteradas apenas na thread principal
  • EnvironmentObject — uma alternativa ao @ObservedObject para passagem implícita através do ambiente

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