@Published ist ein Property Wrapper aus dem Combine-Framework, der automatisch Änderungen einer Klasseneigenschaft veröffentlicht, die dem ObservableObject-Protokoll entspricht. Wenn sich der Wert einer mit @Published markierten Eigenschaft ändert, empfängt SwiftUI ein Signal über objectWillChange und zeichnet alle Ansichten neu, die auf dieses Objekt abonniert sind. Laut der Apple Combine Framework Dokumentation (2025) generiert @Published einen Publisher, der zusätzlich durch Combine-Operatoren wie map, filter, debounce und andere transformiert werden kann. Dies macht @Published zu einer wichtigen Brücke zwischen Daten und Benutzeroberfläche in der MVVM-Architektur.
Wichtige Punkte
objectWillChange aufgerufen, was eine Neuzeichnung der abonnierten Ansichten auslöst$property zugänglich — Abonnieren, Kombinieren und Transformieren des Streams möglich@Published ist ein im Combine-Modul definierter Property Wrapper, der die Möglichkeit hinzufügt, Abonnenten automatisch über Änderungen an einer Klasseneigenschaft zu benachrichtigen. Es kann nur innerhalb einer Klasse (nicht in einer Struktur) und nur für Eigenschaften einer Klasse verwendet werden, die dem ObservableObject-Protokoll entspricht.
Wenn sich der Wert einer @Published-Eigenschaft ändert, generiert Combine ein Ereignis über einen integrierten Publisher, der über das Dollar-Präfix zugänglich ist: $propertyName. Dieser Publisher ist ein ObservableObjectPublisher, der zum ObservableObject selbst gehört. SwiftUI abonniert ihn automatisch, wenn eine Ansicht @ObservedObject oder @StateObject verwendet, und zeichnet die Ansicht neu, wenn sich eine @Published-Eigenschaft innerhalb des Objekts ändert.
Laut Matt Neuburgs Buch „IOS 18 Programming Fundamentals with Swift“ (2025) ist @Published ein praktischer Wrapper über dem willSet-Muster, der automatisch objectWillChange.send() aufruft. Tatsächlich erweitert der Compiler @Published zu einer berechneten Eigenschaft mit einem willSet-Observer, was im Vergleich zur manuellen Implementierung keinen Laufzeit-Overhead verursacht.
Verwenden Sie @Published für alle ObservableObject-Eigenschaften, deren Änderungen in der Benutzeroberfläche widergespiegelt werden sollen. Für Eigenschaften, die die UI nicht beeinflussen, reduzieren normale gespeicherte Eigenschaften ohne @Published unnötige Neuzeichnungen.
@Published generiert zur Kompilierungszeit zwei Schlüsselelemente. Das erste ist eine gespeicherte Eigenschaft mit einem willSet-Observer, der objectWillChange.send() vor dem Schreiben des neuen Werts aufruft. Das zweite ist die Projektion $propertyName, die einen Published.Publisher zurückgibt, der direkt in Combine-Pipelines verwendet werden kann.
Betrachten Sie die Klasse Settings mit drei Eigenschaften: zwei @Published und eine normale:
class Settings: ObservableObject {
@Published var username: String = "Guest"
@Published var isDarkMode = false
var lastLogin: Date = Date() // without @Published
}
Wenn sich username oder isDarkMode ändert, zeichnet SwiftUI alle Ansichten neu, die auf die Settings-Instanz abonniert sind. Das Ändern von lastLogin löst keine Neuzeichnung aus. Wenn Sie Abonnenten manuell über eine Änderung einer normalen Eigenschaft benachrichtigen müssen, können Sie objectWillChange.send() im willSet-Observer aufrufen.
Ein wichtiges Detail: @Published veröffentlicht Änderungen nur bei direkter Zuweisung einer Eigenschaft. Wenn die Eigenschaft ein Referenztyp (Klasse) ist und sich ihr interner Zustand ohne Ersetzung der Referenz ändert, erkennt @Published dies nicht. In solchen Fällen ist manuelles Senden von Ereignissen oder der Wechsel zu einem Wertetyp (Struktur) erforderlich.
@Published ist eng mit Combine integriert — jede @Published-Eigenschaft stellt automatisch einen Publisher bereit, der über die Projektion $propertyName zugänglich ist. Dies ermöglicht die Verwendung von Combine-Operatoren zum Filtern, Transformieren, Kombinieren und zur verzögerten Wertverarbeitung.
Ein typisches Szenario ist die Suche mit Debounce. Ein Eingabefeld ist an die @Published-Eigenschaft searchText gebunden, aber die Serveranfrage soll erst nach einer Pause von 300 ms gesendet werden. Combine mit $searchText.debounce löst dies in einer Zeile:
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) { }
}
Laut John Sundells Artikel (Swift by Sundell, 2024) ist die Kombination von @Published mit Combine ein Standardmuster für reaktive Pipelines in SwiftUI-Anwendungen: Validierung, Debounce, Throttle, CombineLatest, Merge mit anderen Publishern. @Published fungiert als Brücke zwischen imperativem UI-Code und reaktivem Combine.
Mit der Veröffentlichung von iOS 17 führte Apple das @Observable-Makro ein, das einen alternativen Ansatz für Reaktivität ohne ObservableObject und @Published bietet. @Observable verfolgt automatisch den Zugriff auf Eigenschaften auf Leseebene statt auf Schreibeebene, was präzisere Neuzeichnungen ermöglicht — nur die Ansicht, die eine bestimmte geänderte Eigenschaft liest, wird aktualisiert.
Dies bedeutet jedoch nicht, dass @Published veraltet ist. @Published bleibt notwendig, wenn eine Integration mit Combine-Pipelines erforderlich ist — die Projektion $propertyName bietet einen Publisher, den @Observable nicht hat. Darüber hinaus ist @Published+ObservableObject für die Abwärtskompatibilität mit iOS 16 und darunter die einzige Option. Laut der Apple WWDC 2023-Sitzung „Discover Observation in SwiftUI“ empfiehlt Apple @Observable für neue Projekte, behält aber explizit die Unterstützung für @Published für vorhandenen Code und Combine-Szenarien bei.
In der Praxis verwenden viele Projekte einen hybriden Ansatz: Neue Datenmodelle verwenden @Observable, während vorhandene ObservableObject mit @Published ohne Refactoring bleiben. @Published ist auch unverzichtbar, wenn eine feinkörnige Kontrolle über die Veröffentlichung erforderlich ist — zum Beispiel die Verzögerung der Benachrichtigung, bis eine Batch-Aktualisierung mehrerer Eigenschaften abgeschlossen ist.
Der erste Fehler ist die Verwendung von @Published in einer Struktur. Der Compiler gibt einen Fehler aus: „Property wrapper cannot be applied to a computed property“ oder „‘@Published’ is only available on members of a class.“ @Published erfordert Referenzsemantik, da ObservableObjectPublisher eine Klasse ist, die für jede Instanz eindeutig sein muss.
Der zweite Fehler ist das Mutieren des Inhalts einer Referenzeigenschaft ohne Ersetzen der Referenz. Wenn eine @Published-Eigenschaft vom Typ Array [String] ist und Sie array.append("new") aufrufen, erkennt @Published die Änderung nicht, da sich die Referenz auf das Array nicht geändert hat. Lösung: Weisen Sie der Eigenschaft einen neuen Wert zu array = array + ["new"] oder verwenden Sie objectWillChange.send() manuell.
Der dritte Fehler ist eine übermäßige Anzahl von @Published-Eigenschaften. Jede @Published-Eigenschaft löst eine Neuzeichnung aller Ansichten aus, die auf das ObservableObject abonniert sind, nicht nur derer, die diese Eigenschaft lesen. Laut Point-Free (2025) reduziert die Aufteilung eines großen ObservableObject in mehrere kleinere mit @StateObject und @EnvironmentObject unnötige Neuzeichnungen und verbessert die Leistung.
Das erste Beispiel ist ein ViewModel für ein Registrierungsformular mit Validierung. Die @Published-Eigenschaften email und password lösen die Anzeige von Validierungsfehlern über eine Combine-Pipeline aus:
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)
}
}
Das zweite Beispiel ist die manuelle Veröffentlichung für eine Sammlung von Referenzelementen. Anstatt das gesamte Array bei jeder Änderung innerhalb eines Elements zu ersetzen, wird objectWillChange.send() verwendet:
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() // manual notification
}
}
Das dritte Beispiel ist Assign an eine @Published-Eigenschaft über Combine. Mit der neuen Swift 5.9-Syntax können Sie direkt über die Projektion assign(to: &$property) ohne Optional-Wrapper zuweisen. Dies ist der kürzeste Weg, einen Publisher mit einer @Published-Eigenschaft zu verbinden, ohne ein Abonnement zu erstellen.
Häufig gestellte Fragen
Nein, @Published kann nur innerhalb einer Klasse verwendet werden, die ObservableObject entspricht. In Strukturen verwenden Sie @State für lokalen Zustand oder @Bindable mit dem @Observable-Makro in iOS 17+. Der Versuch, @Published in einer Struktur zu verwenden, führt zu einem Kompilierungsfehler.
Richtiger Ansatz: Weisen Sie den neuen Wert vollständig zu (array = array + ["new"]). @Published verfolgt die Referenzersetzung, nicht die Inhaltsänderung. Für Sammlungen von Referenztypen verwenden Sie den manuellen Aufruf objectWillChange.send() nach dem Mutieren des internen Zustands von Elementen.
@State ist für lokalen Zustand innerhalb einer einzelnen Ansicht konzipiert und funktioniert nur mit Wertetypen. @Published ist für ObservableObject-Eigenschaften, die von mehreren Ansichten über @ObservedObject oder @EnvironmentObject gelesen werden können. @State ist einfacher, @Published ist dank der Combine-Integration leistungsfähiger.
Nur diejenigen, deren Änderungen die UI aktualisieren sollen. Eigenschaften für interne Berechnungen, Caches oder temporäre Flags benötigen kein @Published — dies reduziert unnötige Neuzeichnungen. Verwenden Sie @Published als Signal, dass „diese Eigenschaft für die Benutzeroberfläche wichtig ist.“
SwiftUI integriert sich mit Core Data über @FetchRequest und @ObservedObject für NSManagedObject. ManagedObject entspricht bereits ObservableObject, daher ist @Published nicht erforderlich — NSManagedObject benachrichtigt Änderungen selbst. @Published wird in der ViewModel-Schicht zwischen Core Data und UI für die Datentransformation verwendet.
Zusammenfassung
objectWillChange.send() auf und generiert einen Publisher über die Projektion $propertyassign(to: &$property) in Swift 5.9 ermöglicht das direkte Abonnieren eines Publishers auf eine @Published-EigenschaftWir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch