@ObservedObject: qué es, cómo funciona y ejemplos

Autor: IT Sectr Publicado: 2026-06-19 Tiempo de lectura: 7 min

@ObservedObject es un Property Wrapper en SwiftUI para observar una instancia de ObservableObject pasada desde el exterior. A diferencia de @StateObject, @ObservedObject no crea un objeto, sino que se suscribe a cambios de uno ya existente. Según la Documentación para Desarrolladores de Apple (2025), @ObservedObject se utiliza en vistas hijo que necesitan rastrear datos que pertenecen al padre. @ObservedObject proporciona una conexión reactiva sin gestionar el ciclo de vida del objeto.

Puntos clave

  • @ObservedObject — Property Wrapper para observar ObservableObject sin propiedad
  • Sin creación — el objeto se pasa desde la vista padre o el entorno
  • @Published — propiedades dentro de ObservableObject cuyos cambios rastrea SwiftUI
  • Re-renderizado — cuando una propiedad @Published cambia, SwiftUI actualiza todas las vistas suscritas
  • No confundir con @StateObject — @ObservedObject no garantiza una única instancia

¿Qué es @ObservedObject en SwiftUI?

@ObservedObject es un Property Wrapper que suscribe una vista a los cambios de un ObservableObject. ObservableObject es un protocolo del framework Combine que requiere implementar un publisher objectWillChange. Cuando cualquier propiedad marcada con @Published cambia dentro del ObservedObject, el publisher envía una señal y SwiftUI re-renderiza todas las vistas suscritas a través de @ObservedObject.

La característica principal de @ObservedObject es la ausencia de propiedad. La vista no es responsable de crear o destruir el objeto. El objeto se crea en la vista padre (mediante @StateObject) o se inyecta a través de @EnvironmentObject. La vista hijo solo observa los cambios y recibe actualizaciones. Si el objeto se reemplaza en el padre, @ObservedObject cambia a la nueva instancia.

@ObservedObject es adecuado para escenarios de compartición de datos: modelo de usuario, configuraciones comunes, estado de conexión al servidor. Cuando varias vistas en diferentes niveles de la jerarquía necesitan mostrar los mismos datos, @ObservedObject en cada vista crea suscripciones independientes pero consistentes a una única fuente.

@ObservedObject vs @StateObject: diferencias clave

La diferencia entre @ObservedObject y @StateObject es uno de los temas más comunes en entrevistas sobre SwiftUI. La regla principal: @StateObject crea y posee el objeto, @ObservedObject observa uno ya existente. Violar esta regla provoca pérdida inesperada de datos o doble inicialización.

Característica@StateObject@ObservedObject
Creación del objetoSí, al inicializar la vistaNo, recibe uno ya creado
PropiedadVista actualComponente padre
Instancia únicaSí, durante todo el ciclo de vidaNo, puede ser reemplazada
Recreación al renderizarNo, persisteDepende del padre
Dónde usarVista raíz propietariaVistas hijo

@StateObject garantiza que el objeto se crea una vez y sobrevive a inicializaciones repetidas de la estructura de la vista. @ObservedObject recibe el objeto desde el exterior y se recrea con cada inicialización de la estructura padre. Si el padre usa @StateObject para el objeto, las vistas hijo pueden usar @ObservedObject de forma segura: el objeto será único en toda la jerarquía.

Cómo rastrea cambios @ObservedObject

El mecanismo de rastreo de @ObservedObject se basa en Combine y el protocolo ObservableObject. Durante la inicialización, SwiftUI llama al publisher objectWillChange: el objeto debe emitir una señal antes de cambiar una propiedad @Published. Combine pasa la señal al grafo de dependencias de SwiftUI, que marca todas las vistas dependientes como necesitadas de actualización. Esto ocurre sincrónicamente antes de que el valor cambie.

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")
        }
    }
}

En el listado WeatherService es un ObservableObject con dos propiedades @Published. WeatherView declara @ObservedObject var weather: WeatherService, recibiendo la instancia del padre. Cuando temperature cambia, objectWillChange se dispara antes de establecer el nuevo valor, SwiftUI re-renderiza WeatherView y se muestra la temperatura actual. La suscripción es gestionada automáticamente por SwiftUI: el desarrollador no necesita llamar a sink ni dispose.

Patrones de uso de @ObservedObject

El primer patrón es pasar un modelo a través del inicializador. El padre crea un ObservableObject mediante @StateObject y lo pasa a las vistas hijo como @ObservedObject. Esta es una transferencia jerárquica estándar de datos donde la vista raíz gestiona el ciclo de vida del modelo y todos los componentes anidados se suscriben a los cambios.

El segundo patrón es EnvironmentObject, una versión global de @ObservedObject a través del entorno de SwiftUI. El objeto se inyecta a nivel de escena o vista raíz y está disponible automáticamente para todos los componentes hijo sin necesidad de pasarlo explícitamente por inicializadores. Dentro de la vista hijo, @EnvironmentObject funciona de manera similar a @ObservedObject pero recibe el objeto del entorno.

El tercer patrón es la composición de múltiples ObservableObject. En aplicaciones complejas, una vista puede observar varios objetos: @ObservedObject var user: UserService, @ObservedObject var network: NetworkMonitor. Esto separa responsabilidades entre servicios y mantiene la testabilidad 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 y NetworkMonitor. Cada objeto maneja su propio dominio de datos y notifica independientemente a la vista sobre los cambios. Si la red se desconecta, NetworkMonitor cambia isConnected y SwiftUI re-renderiza DashboardView, actualizando el color del indicador. La composición de ObservableObject es la forma preferida de organizar datos en aplicaciones SwiftUI.

@Published: el vínculo entre ObservableObject y SwiftUI

@Published es un Property Wrapper de Combine que añade automáticamente un publisher a una propiedad dentro de ObservableObject. Cuando una propiedad @Published cambia, Combine genera un evento a través del publisher objectWillChange. SwiftUI se suscribe a este publisher al usar @ObservedObject o @StateObject y re-renderiza la vista con cada nuevo valor.

@Published soporta todos los tipos, incluyendo opcionales, colecciones y estructuras personalizadas. Sin embargo, para colecciones (arrays, diccionarios), SwiftUI solo rastrea el reemplazo de la referencia, no la mutación del contenido. Para detectar la adición o eliminación de un elemento, es necesario reasignar la colección completa o usar ObservableObject con objectWillChange.send() manual.

Un detalle importante: @Published debe usarse solo dentro de una clase que implemente ObservableObject. Usar @Published fuera de ObservableObject causará un error de compilación. Además, @Published no se puede aplicar a propiedades de inicialización perezosa (lazy var) ni a propiedades calculadas.

Errores comunes con @ObservedObject

El error más crítico es usar @ObservedObject para crear un objeto. Si escribes @ObservedObject var model = UserViewModel() en la vista padre, cada renderizado creará una nueva instancia de UserViewModel. Los datos se perderán y las suscripciones @Published se recrearán. Usa siempre @StateObject para la creación y @ObservedObject solo para recibir un objeto ya creado.

El segundo error es modificar propiedades @Published fuera del hilo principal. ObservableObject usa Combine, que requiere enviar cambios en el hilo principal (main actor). Si cambias @Published en una cola en segundo plano, SwiftUI podría re-renderizar la vista en un momento inadecuado, causando condiciones de carrera. Usa DispatchQueue.main.async o @MainActor para las actualizaciones.

El tercer problema son las actualizaciones cíclicas. Si un cambio de @Published desencadena efectos secundarios que vuelven a cambiar @Published, se produce un bucle infinito de re-renderizados. La solución: usar banderas de protección (isUpdating) o separar la lógica en diferentes ObservableObject con límites de responsabilidad claros.

Preguntas frecuentes

¿Puede @ObservedObject ser opcional?

Sí, SwiftUI soporta @ObservedObject var model: UserViewModel?. Sin embargo, la vista no se suscribirá a cambios mientras el objeto sea nil. Cuando se asigna un valor, la suscripción se activa automáticamente.

¿En qué se diferencia @ObservedObject de @EnvironmentObject?

@ObservedObject recibe el objeto a través del inicializador, @EnvironmentObject a través del entorno de SwiftUI. @EnvironmentObject no requiere pasar explícitamente por constructores, pero el objeto debe inyectarse en el nivel superior de la jerarquía.

¿Cómo notificar manualmente a SwiftUI sobre un cambio en ObservableObject?

Llama a objectWillChange.send() antes de cambiar la propiedad. Esto es útil cuando @Published no es adecuado (por ejemplo, para propiedades calculadas u operaciones con colecciones donde necesitas informar del cambio antes de la mutación).

¿Por qué @ObservedObject no re-renderiza la vista al cambiar dentro de un array?

@ObservedObject y @Published rastrean el reemplazo de la referencia, no la mutación del contenido de la colección. Para provocar un re-renderizado, necesitas reasignar el array: items.append(newItem) → items = items o usar objectWillChange.send() antes de la mutación.

¿Se puede usar @ObservedObject en una estructura que no implemente View?

No, @ObservedObject es un Property Wrapper de SwiftUI disponible solo dentro de tipos que implementan el protocolo View. Para estructuras normales, usa Combine directamente con ObservableObjectPublisher.

Resumen

  • @ObservedObject — Property Wrapper para observar ObservableObject sin propiedad
  • @StateObject — crea el objeto, @ObservedObject — observa uno existente
  • @Published — publisher automático para propiedades de ObservableObject
  • Suscripción — SwiftUI gestiona automáticamente la suscripción Combine al usar @ObservedObject
  • Composición — una vista puede observar múltiples ObservableObject simultáneamente
  • Main actor — las propiedades @Published deben cambiarse solo en el hilo principal
  • EnvironmentObject — una alternativa a @ObservedObject para paso implícito a través del entorno

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