@Published: vad är det, funktionsprincip och tillämpning

Författare: IT Sectr Publicerad: 2026-06-19 Lästid: 8 min

@Published — är en property wrapper från Combine-ramverket som automatiskt publicerar ändringar av en klass egenskap som följer ObservableObject-protokollet. När värdet för en egenskap märkt med @Published ändras, tar SwiftUI emot en signal via objectWillChange och ritar om alla vyer som prenumererar på detta objekt. Enligt Apple Combine Framework Documentation (2025) genererar @Published en Publisher som kan transformeras ytterligare genom Combine-operatorerna: map, filter, debounce och andra. Detta gör @Published till en viktig brygga mellan data och användargränssnittet i MVVM-arkitekturen.

Huvudpunkter

  • @Published — property wrapper för automatisk publicering av ändringar av ObservableObject-egenskaper i SwiftUI och Combine
  • Mekanism: när värdet ändras anropas objectWillChange, vilket utlöser omritning av prenumererade vyer
  • Publisher är tillgänglig via projektionen $property — man kan prenumerera, kombinera och transformera flödet
  • ObservedObject och StateObject prenumererar automatiskt på @Published-egenskaper — manuell prenumeration krävs inte
  • iOS 17+ @Observable-makrot erbjuder ett alternativ, men @Published förblir standarden för Combine-pipelines

Vad är @Published?

@Published — är en property wrapper definierad i Combine-modulen som ger en klass egenskap möjligheten att automatiskt meddela prenumeranter om ändringar. Den kan endast tillämpas inom en klass (inte i en struktur) och endast på egenskaper i en klass som följer ObservableObject-protokollet.

När värdet för en @Published-egenskap ändras genererar Combine en händelse genom den inbyggda publishern, tillgänglig via dollarprefix: $propertyName. Denna publisher är en ObservableObjectPublisher, som tillhör ObservableObject själv. SwiftUI prenumererar automatiskt på den när en vy använder @ObservedObject eller @StateObject, och ritar om vyn vid varje ändring av en @Published-egenskap inuti objektet.

Enligt Matt Neuburgs bok „IOS 18 Programming Fundamentals with Swift” (2025) är @Published en bekväm omslag runt willSet-mönstret som automatiskt anropar objectWillChange.send(). Kompilatorn vecklar faktiskt ut @Published till en beräknad egenskap med en willSet-observatör, vilket ger noll overhead vid körning jämfört med manuell implementering.

Använd @Published för alla ObservableObject-egenskaper vars ändringar ska reflekteras i gränssnittet. För egenskaper som inte påverkar UI minskar vanliga stored properties utan @Published antalet onödiga omritningar.

Hur @Published fungerar

@Published genererar två nyckelelement vid kompilering. Det första — en lagrad egenskap med en willSet-observatör som anropar objectWillChange.send() innan det nya värdet skrivs. Det andra — projektionen $propertyName som returnerar en Published.Publisher som kan användas direkt i Combine-pipelines.

Betrakta klassen Settings med tre egenskaper: två @Published och en vanlig:

swift
class Settings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isDarkMode = false
    var lastLogin: Date = Date()  // utan @Published
}

När username eller isDarkMode ändras ritar SwiftUI om alla vyer som prenumererar på Settings-instansen. Ändring av lastLogin utlöser ingen omritning. Om du behöver manuellt meddela prenumeranter om ändring av en vanlig egenskap kan du anropa objectWillChange.send() i willSet-observatören.

En viktig detalj: @Published publicerar ändringar endast vid direkt tilldelning till egenskapen. Om egenskapen är av referenstyp (klass) och dess interna tillstånd ändras utan att referensen ersätts, kommer @Published inte att upptäcka det. I sådana fall krävs manuell sändning av händelsen eller ersättning med en värdetyp (struktur).

@Published och Combine

@Published är nära integrerat med Combine — varje @Published-egenskap tillhandahåller automatiskt en publisher tillgänglig via projektionen $propertyName. Detta gör det möjligt att tillämpa Combine-operatorer för filtrering, transformering, kombination och fördröjd bearbetning av värden.

Ett typiskt scenario — sökning med debounce. Inmatningsfältet är bundet till den @Published-egenskapen searchText, men begäran till servern ska endast skickas efter en paus på 300 ms. Combine med $searchText.debounce löser detta på en rad:

swift
class SearchViewModel: ObservableObject {
    @Published var searchText = ""
    @Published var results: [String] = []
    private var cancellables = Set<AnyCancellable>()

    init() {
        setupSearchSubscription()
    }

    private func setupSearchSubscription() {
        $searchText
            .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
            .removeDuplicates()
            .sink { [weak self] text in
                self?.performSearch(text)
            }
            .store(in: &cancellables)
    }

    private func performSearch(_ text: String) { }
}

Enligt John Sundells artikel (Swift by Sundell, 2024) är kombinationen av @Published med Combine ett standardmönster för reaktiva pipeliner i SwiftUI-applikationer: validation, debounce, throttle, combineLatest, merge med andra publishers. @Published fungerar som en brygga mellan imperativ UI-kod och reaktiv Combine.

@Published vs @Observable-makrot

Med lanseringen av iOS 17 introducerade Apple @Observable-makrot, som erbjuder ett alternativt tillvägagångssätt för reaktivitet utan ObservableObject och @Published. @Observable spårar automatiskt åtkomst till egenskaper på läsnivå, inte skrivnivå, vilket ger mer exakta omritningar — endast den vy som läser den specifikt ändrade egenskapen uppdateras.

Men det betyder inte att @Published är föråldrad. @Published förblir nödvändig när integration med Combine-pipelines behövs — projektionen $propertyName ger en publisher som @Observable inte har. Dessutom, för bakåtkompatibilitet med iOS 16 och äldre, är @Published+ObservableObject det enda alternativet. Enligt Apple WWDC 2023-sessionen „Discover Observation in SwiftUI” rekommenderar Apple @Observable för nya projekt, men behåller uttryckligen stödet för @Published för befintlig kod och Combine-scenarier.

I praktiken använder många projekt en hybridansats: nya datamodeller skrivs med @Observable, medan befintliga ObservableObject med @Published förblir utan omfaktorering. @Published är också oersättlig när fin kontroll över publicering krävs — till exempel att fördröja meddelandet tills batchuppdateringen av flera egenskaper är klar.

Vanliga misstag med @Published

Första misstaget — tillämpning av @Published i en struktur. Kompilatorn visar ett fel: „Property wrapper cannot be applied to a computed property” eller „'@Published' is only available on members of a class”. @Published kräver referenssemantik eftersom ObservableObjectPublisher är en klass som måste vara unik för varje instans.

Andra misstaget — mutering av innehållet i en referensegenskap utan att ersätta referensen. Om en @Published-egenskap är av typen array [String] och du anropar array.append("new"), kommer @Published inte att upptäcka ändringen eftersom referensen till arrayen inte har ändrats. Lösning: tilldela egenskapen ett nytt värde array = array + ["new"] eller använd objectWillChange.send() manuellt.

Tredje misstaget — för många @Published-egenskaper. Varje @Published-egenskap utlöser omritning av alla vyer som prenumererar på ObservableObject, inte bara de som läser denna egenskap. Enligt Point-Free (2025) minskar uppdelningen av en stor ObservableObject i flera små med @StateObject och @EnvironmentObject antalet onödiga omritningar och förbättrar prestandan.

Kodexempel

Första exemplet — ViewModel för ett registreringsformulär med validering. @Published-egenskaperna email och password utlöser visning av valideringsfel genom Combine-pipelinen:

swift
class RegistrationViewModel: ObservableObject {
    @Published var email = ""
    @Published var password = ""
    @Published var emailError: String?
    @Published var isFormValid = false
    private var cancellables = Set<AnyCancellable>()

    init() {
        $email
            .map { $0.contains("@") ? nil : "Invalid email" }
            .assign(to: &$emailError)
            .store(in: &cancellables)

        $email.combineLatest($password)
            .map { !$0.isEmpty && !$1.isEmpty }
            .assign(to: &$isFormValid)
            .store(in: &cancellables)
    }
}

Andra exemplet — manuell publicering för en samling referenselement. Istället för att ersätta hela arrayen vid varje ändring inuti ett element används objectWillChange.send():

swift
class TodoItem {
    var title: String
    var isDone = false
    init(title: String) { self.title = title }
}

class TodoListViewModel: ObservableObject {
    @Published var items: [TodoItem] = []

    func toggle(item: TodoItem) {
        item.isDone.toggle()
        self.objectWillChange.send()  // manuellt meddelande
    }
}

Tredje exemplet — Assign till en @Published-egenskap via Combine. Med den nya syntaxen i Swift 5.9 kan man direkt tilldela via projektionen assign(to: &$property) utan Optional-omslag. Detta är den kortaste vägen att koppla en publisher till en @Published-egenskap utan att skapa en prenumeration.

Vanliga frågor

Kan @Published användas i en struktur?

Nej, @Published kan endast tillämpas inom en klass som följer ObservableObject. I strukturer använder du @State för lokalt tillstånd eller @Bindable med @Observable-makrot i iOS 17+. Ett försök att tillämpa @Published i en struktur kommer att orsaka ett kompileringsfel.

Hur fungerar @Published med arrayer och ordböcker?

Korrekt: tilldela ett nytt värde i sin helhet (array = array + ["new"]). @Published spårar ersättning av referensen, inte mutering av innehållet. För samlingar av referenstyper, använd manuellt anrop av objectWillChange.send() efter mutering av elementens interna tillstånd.

Vad är skillnaden mellan @Published och @State?

@State är avsett för lokalt tillstånd inom en vy och fungerar endast med värdetyper. @Published — för ObservableObject-egenskaper som kan läsas av flera vyer via @ObservedObject eller @EnvironmentObject. @State är enklare, @Published är kraftfullare tack vare integrationen med Combine.

Krävs @Published för varje ObservableObject-egenskap?

Endast för de vars ändringar ska uppdatera UI. Egenskaper för interna beräkningar, cache eller temporära flaggor kräver inte @Published — detta minskar antalet onödiga omritningar. Använd @Published som en signal –den här egenskapen är viktig för gränssnittet”.

Hur fungerar @Published med Core Data?

SwiftUI integreras med Core Data genom @FetchRequest och @ObservedObject för NSManagedObject. ManagedObject följer redan ObservableObject, så @Published behövs inte — NSManagedObject själv meddelar om ändringar. @Published används i ViewModel-lagret mellan Core Data och UI för datatransformering.

Sammanfattning

  • @Published — property wrapper från Combine, publicerar automatiskt ändringar av ObservableObject-egenskaper för SwiftUI och Combine-pipelines
  • Mekanism: willSet-observatören anropar objectWillChange.send(), genererar en publisher via projektionen $property
  • Combine: @Published tillhandahåller en publisher för debounce, map, combineLatest och andra operatorer — det är bryggan mellan UI och reaktiva pipeliner
  • @Observable (iOS 17+) — alternativ för nya projekt, men @Published förblir standarden för Combine och bakåtkompatibilitet
  • Misstag: @Published fungerar inte i strukturer, spårar inte mutering av referenstyper, för många @Published ökar omritningar
  • Best practice: markera endast UI-påverkande egenskaper med @Published, dela upp stora ObservableObject i flera små
  • Assign: assign(to: &$property) i Swift 5.9 möjliggör direkt prenumeration av en publisher på en @Published-egenskap

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å