@Published: mi ez, működési elv és alkalmazás

Szerző: IT Sectr Megjelenés: 2026-06-19 Olvasási idő: 8 perc

@Published — egy property wrapper a Combine keretrendszerből, amely automatikusan közzéteszi az ObservableObject protokollnak megfelelő osztály tulajdonságának változásait. Amikor a @Published-del jelölt tulajdonság értéke megváltozik, a SwiftUI jelet kap a objectWillChange-en keresztül, és újrarajzolja az összes, erre az objektumra feliratkozott nézetet. Az Apple Combine Framework Documentation (2025) szerint a @Published egy Publisher-t generál, amely tovább transzformálható a Combine operátorokkal: map, filter, debounce és mások. Ez teszi a @Published-et kulcsfontosságú hídá az adatok és a felhasználói felület között az MVVM architektúrában.

Főbb pontok

  • @Published — property wrapper az ObservableObject tulajdonságok változásainak automatikus közzétételéhez SwiftUI-ban és Combine-ban
  • Mechanizmus: értékváltozáskor meghívódik a objectWillChange, ami kiváltja a feliratkozott nézetek újrarajzolását
  • Publisher elérhető a $property projekción keresztül — fel lehet iratkozni, kombinálni és transzformálni az adatfolyamot
  • ObservedObject és StateObject automatikusan feliratkoznak a @Published tulajdonságokra — kézi feliratkozás nem szükséges
  • iOS 17+ az @Observable makró alternatívát kínál, de a @Published marad a szabvány a Combine pipeline-okhoz

Mi az @Published?

@Published — egy property wrapper, amely a Combine modulban van definiálva, és lehetővé teszi egy osztály tulajdonságának, hogy automatikusan értesítse a feliratkozókat a változásokról. Csak osztályon belül (nem struktúrában) és csak az ObservableObject protokollnak megfelelő osztály tulajdonságaira alkalmazható.

Amikor egy @Published tulajdonság értéke megváltozik, a Combine eseményt generál a beépített publisher-en keresztül, amely a dollár előtaggal érhető el: $propertyName. Ez a publisher egy ObservableObjectPublisher, amely magához az ObservableObject-hez tartozik. A SwiftUI automatikusan feliratkozik rá, amikor egy nézet @ObservedObject vagy @StateObject használ, és újrarajzolja a nézetet az objektumon belüli bármely @Published tulajdonság változásakor.

Matt Neuburg „IOS 18 Programming Fundamentals with Swift” (2025) című könyve szerint a @Published egy kényelmes burkoló a willSet pattern körül, amely automatikusan meghívja a objectWillChange.send()-et. A fordító gyakorlatilag egy számított tulajdonsággá bontja ki a @Published-et egy willSet megfigyelővel, ami nulla többletterhelést jelent futásidőben a kézi implementációhoz képest.

Használja a @Published-et minden olyan ObservableObject tulajdonsághoz, amelyek változásainak tükröződniük kell a felületen. Azokhoz a tulajdonságokhoz, amelyek nem befolyásolják a UI-t, a @Published nélküli szokásos stored properties csökkenti a szükségtelen újrarajzolások számát.

Hogyan működik az @Published

@Published két kulcselemet generál fordításkor. Az első — egy tárolt tulajdonság egy willSet megfigyelővel, amely meghívja a objectWillChange.send()-et az új érték írása előtt. A második — a $propertyName projekció, amely egy Published.Publisher-t ad vissza, ami közvetlenül használható a Combine pipeline-okban.

Tekintsük a Settings osztályt három tulajdonsággal: kettő @Published és egy szokásos:

swift
class Settings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isDarkMode = false
    var lastLogin: Date = Date()  // @Published nélkül
}

A username vagy isDarkMode változásakor a SwiftUI újrarajzolja a Settings példányra feliratkozott összes nézetet. A lastLogin változása nem vált ki újrarajzolást. Ha kézzel szeretné értesíteni a feliratkozókat egy szokásos tulajdonság változásáról, meghívhatja a objectWillChange.send()-et a willSet megfigyelőben.

Fontos részlet: a @Published csak közvetlen értékadáskor teszi közzé a változásokat. Ha a tulajdonság referenciatípusú (osztály), és a belső állapota a referencia cseréje nélkül változik, a @Published nem érzékeli azt. Ilyen esetekben kézi eseményküldésre vagy értéktípusra (struktúrára) cserélésre van szükség.

@Published és Combine

@Published szorosan integrálódik a Combine-nal — minden @Published tulajdonság automatikusan biztosít egy publisher-t, amely a $propertyName projekción keresztül érhető el. Ez lehetővé teszi a Combine operátorok alkalmazását szűréshez, transzformációhoz, kombináláshoz és késleltetett értékfeldolgozáshoz.

Egy tipikus forgatókönyv — keresés debounce-szal. A beviteli mező a @Published searchText tulajdonsághoz van kötve, de a kérést a szerverhez csak 300 ms szünet után kell elküldeni. A Combine a $searchText.debounce-szal egy sorban megoldja ezt:

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

John Sundell cikke (Swift by Sundell, 2024) szerint a @Published és a Combine kombinálása standard minta a reaktív pipeline-okhoz SwiftUI alkalmazásokban: validation, debounce, throttle, combineLatest, merge más publisher-ekkel. A @Published hídként működik az imperatív UI kód és a reaktív Combine között.

@Published vs @Observable makró

Az iOS 17 megjelenésével az Apple bevezette a @Observable makrót, amely alternatív megközelítést kínál a reaktivitáshoz ObservableObject és @Published nélkül. A @Observable automatikusan nyomon követi a tulajdonságokhoz való hozzáférést olvasási szinten, nem írási szinten, ami pontosabb újrarajzolást eredményez — csak az a nézet frissül, amelyik az adott megváltoztatott tulajdonságot olvassa.

Ez azonban nem jelenti azt, hogy a @Published elavult. A @Published továbbra is szükséges, amikor a Combine pipeline-okkal való integrációra van szükség — a $propertyName projekció olyan publisher-t biztosít, amilyennel a @Observable nem rendelkezik. Ezenkívül az iOS 16 és korábbi verziókkal való visszafelé kompatibilitás miatt a @Published+ObservableObject az egyetlen lehetőség. Az Apple WWDC 2023 „Discover Observation in SwiftUI” ülésszakasz szerint az Apple az @Observable-t ajánlja új projektekhez, de kifejezetten fenntartja a @Published támogatását a meglévő kódhoz és a Combine forgatókönyvekhez.

A gyakorlatban sok projekt hibrid megközelítést használ: az új adatmodelleket @Observable-val írják, a meglévő ObservableObject-ek @Published-del pedig refaktorálás nélkül maradnak. A @Published akkor is nélkülözhetetlen, amikor finom kontrollra van szükség a közzététel felett — például az értesítés késleltetése több tulajdonság batch frissítésének befejeződéséig.

Gyakori hibák az @Published-del

Első hiba — a @Published alkalmazása struktúrában. A fordító hibát jelez: „Property wrapper cannot be applied to a computed property” vagy „'@Published' is only available on members of a class”. A @Published referenciális szemantikát igényel, mert az ObservableObjectPublisher egy osztály, amelynek minden példányhoz egyedinek kell lennie.

Második hiba — referencia tulajdonság tartalmának megváltoztatása a referencia cseréje nélkül. Ha egy @Published tulajdonság típusa [String] tömb, és ön meghívja a array.append("new")-t, a @Published nem érzékeli a változást, mert a tömbre mutató referencia nem változott. Megoldás: rendeljen új értéket a tulajdonsághoz array = array + ["new"] vagy használja kézzel a objectWillChange.send()-et.

Harmadik hiba — túl sok @Published tulajdonság. Minden @Published tulajdonság az ObservableObject-re feliratkozott összes nézet újrarajzolását kiváltja, nem csak azokét, amelyek ezt a tulajdonságot olvassák. A Point-Free (2025) szerint egy nagy ObservableObject több kicsire bontása @StateObject és @EnvironmentObject segítségével csökkenti a szükségtelen újrarajzolások számát és javítja a teljesítményt.

Kódpéldák

Első példa — regisztrációs űrlap ViewModel-je validációval. A @Published email és password tulajdonságok a Combine pipeline-on keresztül kiváltják a validációs hibák megjelenítését:

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

Második példa — kézi közzététel referencia elemek gyűjteményéhez. Ahelyett, hogy az egész tömböt lecserélné minden elemen belüli változáskor, a objectWillChange.send() használata:

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()  // kézi értesítés
    }
}

Harmadik példa — Assign egy @Published tulajdonsághoz Combine-on keresztül. A Swift 5.9 új szintaxisát használva közvetlenül hozzárendelhető a assign(to: &$property) projekción keresztül Optional burkoló nélkül. Ez a legrövidebb út egy publisher és egy @Published tulajdonság összekapcsolására anélkül, hogy feliratkozást hoznánk létre.

Gyakran Ismételt Kérdések

Használható a @Published struktúrában?

Nem, a @Published csak ObservableObject-nek megfelelő osztályon belül alkalmazható. Struktúrákban használja a @State-t lokális állapothoz vagy a @Bindable-t az @Observable makróval iOS 17+-ban. A @Published struktúrában való alkalmazásának kísérlete fordítási hibát okoz.

Hogyan működik a @Published tömbökkel és szótárakkal?

Helyesen: rendeljen új értéket egészében (array = array + ["new"]). A @Published a referencia cseréjét követi, nem a tartalom megváltoztatását. Referenciatípusú gyűjtemények esetén használja a objectWillChange.send() kézi meghívását az elemek belső állapotának megváltoztatása után.

Miben különbözik a @Published a @State-től?

@State egy nézeten belüli lokális állapothoz való, és csak értéktípusokkal működik. A @Published — ObservableObject tulajdonságokhoz, amelyeket több nézet is olvashat @ObservedObject vagy @EnvironmentObject segítségével. A @State egyszerűbb, a @Published erősebb a Combine integrációnak köszönhetően.

Szükséges a @Published minden ObservableObject tulajdonsághoz?

Csak azokhoz, amelyek változásainak frissíteniük kell a UI-t. A belső számításokhoz, győrűtérhez vagy ideiglenes jelzőkhöz nem szükséges @Published — ez csökkenti a szükségtelen újrarajzolások számát. Használja a @Published-et jeleként: „ez a tulajdonság fontos a felület számára”.

Hogyan működik a @Published a Core Data-val?

A SwiftUI a Core Data-val a @FetchRequest és az NSManagedObject-hez való @ObservedObject segítségével integrálódik. A ManagedObject már megfelel az ObservableObject-nek, így a @Published nem szükséges — az NSManagedObject maga értesít a változásokról. A @Published a ViewModel rétegben használatos a Core Data és a UI között adat transzformációhoz.

Összefoglaló

  • @Published — property wrapper a Combine-ból, automatikusan közzéteszi az ObservableObject tulajdonságok változásait SwiftUI és Combine pipeline-ok számára
  • Mechanizmus: a willSet megfigyelő meghívja a objectWillChange.send()-et, és publisher-t generál a $property projekción keresztül
  • Combine: a @Published publisher-t biztosít debounce, map, combineLatest és más operátorok számára — ez a híd a UI és a reaktív pipeline-ok között
  • @Observable (iOS 17+) — alternatíva új projektekhez, de a @Published marad a szabvány a Combine és a visszafelé kompatibilitás számára
  • Hibák: a @Published nem működik struktúrákban, nem követi a referenciatípusok megváltoztatását, túl sok @Published növeli az újrarajzolásokat
  • Best practice: csak a UI-t befolyásoló tulajdonságokat jelölje @Published-del, a nagy ObservableObject-eket ossza több kicsire
  • Assign: assign(to: &$property) a Swift 5.9-ben lehetővé teszi a publisher közvetlen feliratkoztatását egy @Published tulajdonságra

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is