@ObservedObject: vad det är, observera objekt och uppdatera View

Författare: IT Sectr Publicerad: 2026-06-26 Lästid: 9 min

@ObservedObject är en property wrapper i SwiftUI som gör att en View kan observera ändringar i ett ObservableObject som skapats på en annan plats i hierarkin. Till skillnad från @StateObject skapar @ObservedObject inte ett objekt — det prenumererar bara på dess publisher objectWillChange och ritar om View vid uppdatering av @Published-egenskaper. Detta gör @ObservedObject till rtt val för underordnade Views som tar emot data från föräldern via initieraren. Enligt Paul Hudsons artikel — Hacking with Swift (2025) byggs en typisk SwiftUI-applikationsarkitektur upp så här: rotvyn använder @StateObject för att skapa en view model och alla underordnade Views tar emot den via @ObservedObject, vilket ger en enda källa till sanning utan dataduplicering.

Huvudpunkter

  • @ObservedObject — property wrapper för att observera ett ObservableObject som skapats i den överordnade vyn.
  • Äger inte objektet — till skillnad från @StateObject hanterar @ObservedObject inte objektets livscykel.
  • Prenumeration på ändringar — vid ändring av @Published-egenskaper ritas View automatiskt om.
  • Överföring via initierare — objektet överförs till den underordnade vyn via initierarens parameter.
  • iOS 13+ — @ObservedObject är tillgängligt från den första versionen av SwiftUI, till skillnad från @StateObject (iOS 14+).

Vad är @ObservedObject i SwiftUI

@ObservedObject är en property wrapper som prenumererar en View på ObservableObject-ändringar. När ett objekt markerat med @ObservedObject ändrar någon av sina egenskaper deklarerade med @Published, ritar SwiftUI automatiskt om vyn. @ObservedObject skapar inte objektet — det etablerar bara en anslutning mellan en befintlig ObservableObject-instans och den View som ska reagera på dess ändringar.

Den viktigaste skillnaden mellan @ObservedObject och @StateObject — är ägande. @ObservedObject förutsätter att objektet har skapats och lagrats någonstans högre upp i View-hierarkin. Den underordnade vyn får en referens till detta objekt via initieraren och observerar det bara. Om den underordnade vyn återskapas får den samma referens från föräldern — data går inte förlorad.

Enligt Apple Developer Documentation — SwiftUI (2025) är @ObservedObject tillgängligt från iOS 13, vilket gör det till det enda alternativet för att observera ObservableObject i projekt som stödjer äldre iOS-versioner. I iOS 14+ föredras @StateObject för att skapa objekt, men @ObservedObject förblir relevant för att överföra befintliga objekt.

Hur fungerar @ObservedObject

Mekanismen för @ObservedObject är baserad på ObservableObject-protokollet från Combine-ramverket. Varje klass som är kompatibel med ObservableObject får automatiskt en publisher objectWillChange som skickar en signal innan någon @Published-egenskap ändras. SwiftUI prenumererar på denna publisher via @ObservedObject och vid mottagning av signalen markerar vyn som att den kräver omritning.

swift
class TaskViewModel: ObservableObject {
    @Published var tasks: [Task] = []
    @Published var isLoading = false
    
    func loadTasks() async {
        isLoading = true
        // hämta data
        isLoading = false
    }
}

struct TaskListView: View {
    @ObservedObject var viewModel: TaskViewModel
    
    var body: some View {
        List(viewModel.tasks) { task in
            Text(task.title)
        }
        .task { await viewModel.loadTasks() }
    }
}

När den överordnade vyn överför viewModel till TaskListView via initieraren, skapar SwiftUI en anslutning mellan objektet och vyn. Vid ändring av tasks-arrayen eller isLoading-flaggan ritar SwiftUI om TaskListView. Objektet förblir oförändrat — det lagras i den överordnade vyn via @StateObject.

@ObservedObject vs @StateObject: när ska vad användas

Skillnaden mellan @ObservedObject och @StateObject — är skillnaden mellan observatör och ägare. @StateObject skapar objektet och hanterar dess livscykel. @ObservedObject observerar bara objektet som har skapats och lagrats på en annan plats. Valet mellan dem bestäms av vymens ansvar för data.

ScenarioRekommendationAnledning
View skapar data@StateObjectView äger objektet och är ansvarig för dess livscykel
View tar emot data@ObservedObjectView observerar bara, objektet lever i föräldern
Stöd för iOS 13@ObservedObject@StateObject inte tillgängligt, använd @ObservedObject med manuell hantering
Återanvändbar komponent@ObservedObjectKomponenten bör inte skapa data — den tar emot den utifrån

Huvudregel: om View skapar ett objekt — @StateObject. Om View tar emot ett objekt — @ObservedObject. Brott mot denna regel till förmån för @ObservedObject för att skapa objekt leder till dataförlust vid ombyggnad av vyn. Brott till förmån för @StateObject för att ta emot objekt skapar en duplicerad instans, oberoende av föräldern.

Exempel på användning av @ObservedObject

Ett typiskt användningsscenario för @ObservedObject — en uppgiftslista, där rotvyn skapar en view model och listcellen tar emot den via @ObservedObject. Varje cell kan anropa metoder i view model och ändringarna visas automatiskt i hela listan, eftersom alla celler observerar samma objekt.

swift
struct TaskRow: View {
    @ObservedObject var viewModel: TaskViewModel
    let task: Task
    
    var body: some View {
        HStack {
            Text(task.title)
            Spacer()
            Button("Klart") {
                viewModel.completeTask(task)
            }
        }
    }
}

struct TaskListContainer: View {
    @StateObject var viewModel = TaskViewModel()
    
    var body: some View {
        List(viewModel.tasks) { task in
            TaskRow(viewModel: viewModel, task: task)
        }
    }
}

I detta exempel skapar TaskListContainer viewModel via @StateObject och varje TaskRow tar emot den via @ObservedObject. När användaren klickar på „Done” i någon rad, ändrar viewModel.completeTask den publicerade egenskapen och alla Views som observerar detta objekt uppdateras automatiskt.

Vanliga misstag med @ObservedObject

Det vanligaste misstaget — att använda @ObservedObject för att skapa ett objekt inuti vyn. När vyn byggs om (t.ex. vid ändring av state), skapar SwiftUI en ny ObservableObject-instans, vilket leder till förlust av all ackumulerad data. Detta misstag är särskilt smärtsamt i NavigationStack, där en användare kan fylla i ett formulär och förlora data vid återgång.

Misstag: @ObservedObject istället för @StateObject

swift
// ❌ Dataförlust: @ObservedObject behåller inte objektet
struct FormView: View {
    @ObservedObject var formVM = FormViewModel()
    // Ny formVM skapas vid varje ombyggnad av View!
}

// ✅ Korrekt: @StateObject behåller objektet
struct FormView: View {
    @StateObject var formVM = FormViewModel()
    // Objekt skapat en gång under vymens livstid
}

Misstag: överföring av @StateObject där @ObservedObject behövs

Om en underordnad View deklarerar samma ObservableObject via @StateObject, skapar den en oberoende kopia. Ändringar i det överordnade objektet syns inte i det underordnade och vice versa. Använd alltid @ObservedObject för underordnade Views som tar emot objektet utifrån.

Alternativ till @ObservedObject i SwiftUI

I modern SwiftUI finns flera alternativ till @ObservedObject, var och en med sina fördelar. Valet beror på applikationsarkitekturen, iOS-versionen och det specifika användningsscenariot.

  • @EnvironmentObject — gör det möjligt att hämta ett objekt från SwiftUI-miljön utan explicit överföring via initieraren. Bekvämt för objekt som behövs på många skärmar, men kräver explicit injicering via .environmentObject().
  • @State + @Binding — för enkla värdestyper behövs inget ObservableObject. Använd @State för lagring och @Binding för överföring till underordnade Views.
  • @AppStorage — för UserDefaults-värden som automatiskt ska synkroniseras med vyn.
  • @SceneStorage — för att spara temporärt tillstånd mellan omstarter av scenen (t.ex. position i en lista).

Valet mellan @ObservedObject och @EnvironmentObject — är en fråga om stil och arkitektur. @ObservedObject visar explicit vymens beroenden via initieraren, vilket gör koden mer förutsägbar. @EnvironmentObject är bekvämt för djupa hierarkier men döljer beroenden, vilket kan försvåra felsökning.

Vanliga frågor

Kan @ObservedObject användas utan @StateObject i föräldern?

Ja, om objektet skapas och lagras utanför SwiftUI — till exempel i AppDelegate eller singleton. I detta fall prenumererar @ObservedObject bara på ändringarna av det befintliga objektet. För objekt som skapas inom SwiftUI-hierarkin behövs dock alltid en @StateObject någonstans högre upp.

Varför uppdaterar @ObservedObject ibland inte vyn?

Den mest sannolika orsaken — egenskapen ändras inte via @Published eller så ändras inte själva objektet, utan dess interna struktur utan anrop av objectWillChange. För samlingar, använd tilldelning av en ny kopia: array.append() räcker inte — hela arrayen måste tilldelas på nytt via array = array + [element].

Påverkar @ObservedObject prestandan?

@ObservedObject i sig skapar ingen betydande belastning. Problem uppstår vid freventa ändringar av @Published-egenskaper — varje ändring utlöser omritning av alla observerande Views. För optimering, använd EquatableView, minska antalet publicerade egenskaper och undvik onödiga uppdateringar.

Vad är skillnaden mellan @ObservedObject och @Binding?

@ObservedObject observerar hela ObservableObject-klassen och ritar om vyn vid varje ändring av dess publicerade egenskaper. @Binding skapar en tvåvägsanslutning med ett specifikt värde (String, Int, Bool) och möjliggör läsning och skrivning. @Binding är lättare och kräver inget ObservableObject.

Kan @ObservedObject och @Published kombineras i samma klass?

Ja, detta är ett standardmönster. @Published inuti ObservableObject integreras automatiskt med @ObservedObject. Varje @Published-egenskap lägger till en observatör till objectWillChange-publishern. När någon av dem ändras, ritas alla Views med @ObservedObject för detta objekt om.

Sammanfattning

  • @ObservedObject — property wrapper för att observera ObservableObject som skapats på en annan plats i hierarkin.
  • Äger inte objektet — till skillnad från @StateObject hanterar @ObservedObject inte livscykeln och skapar inte objektet.
  • Prenumeration via Combine — SwiftUI prenumererar automatiskt på ObservableObjects objectWillChange-publisher.
  • iOS 13+ — @ObservedObject är tillgängligt från den första versionen av SwiftUI, viktigt för projekt med gammalt stöd.
  • Överföring via initierare — objektet överförs explicit till den underordnade vyn, vilket gör beroenden transparenta.
  • Ägandefel — att använda @ObservedObject för att skapa objekt leder till dataförlust vid ombyggnad av vyn.
  • Alternativ — @EnvironmentObject för injicering via miljön, @State/@Binding för värdestyper.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också