@Published: τι είναι, αρχή λειτουργίας και εφαρμογή

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-06-19 Χρόνος ανάγνωσης: 8 λεπ

@Published — είναι ένα property wrapper από το framework Combine που δημοσιεύει αυτόματα τις αλλαγές μιας ιδιότητας κλάσης που συμμορφώνεται με το πρωτόκολλο ObservableObject. Όταν η τιμή ιδιότητας που έχει επισημανθεί με @Published αλλάζει, το SwiftUI λαμβάνει σήμα μέσω objectWillChange και σχεδιάζει ξανά όλες τις προβολές που είναι εγγεγραμμένες σε αυτό το αντικείμενο. Σύμφωνα με την Apple Combine Framework Documentation (2025), το @Published δημιουργεί ένα Publisher που μπορεί να μετασχηματιστεί περαιτέρω μέσω των τελεστών Combine: map, filter, debounce και άλλων. Αυτό κάνει το @Published ένα κλειδί γέφυρα μεταξύ δεδομένων και προγράμματος χρήστη στην αρχιτεκτονική MVVM.

Βασικά σημεία

  • @Published — property wrapper για αυτόματη δημοσίευση αλλαγών ιδιοτήτων ObservableObject σε SwiftUI και Combine
  • Μηχανισμός: κατά την αλλαγή τιμής καλείται το objectWillChange, που πυροδοτεί το ξανασχεδίασμα των εγγεγραμμένων προβολών
  • Publisher είναι προσβάσιμος μέσω της προβολής $property — μπορείτε να εγγραφείτε, να συνδυάζετε και να μετασχηματίζετε τη ροή
  • ObservedObject και StateObject εγγράφονται αυτόματα σε @Published ιδιότητες — δεν απαιτείται χειροκίνητη εγγραφή
  • iOS 17+ το μακρο @Observable προσφέρει μια εναλλακτική, αλλά το @Published παραμένει το πρότυπο για τα pipeline του Combine

Τι είναι το @Published;

@Published — είναι ένα property wrapper που ορίζεται στο module Combine και προσθέτει σε μια ιδιότητα κλάσης τη δυνατότητα να ειδοποιεί αυτόματα τους συνδρομητές για αλλαγές. Μπορεί να εφαρμοστεί μόνο εντός κλάσης (όχι σε struct) και μόνο σε ιδιότητες κλάσης που συμμορφώνεται με το πρωτόκολλο ObservableObject.

Όταν η τιμή μιας @Published ιδιότητας αλλάζει, το Combine δημιουργεί ένα συμβάν μέσω του ενσωματωμένου publisher, προσβάσιμο μέσω του προθήματος δολαρίου: $propertyName. Αυτός ο publisher είναι ένας ObservableObjectPublisher, ο οποίος ανήκει στο ιδιο το ObservableObject. Το SwiftUI εγγράφεται αυτόματα σε αυτόν όταν μια προβολή χρησιμοποιεί @ObservedObject ή @StateObject, και σχεδιάζει ξανά την προβολή σε κάθε αλλαγή οποιασδήποτε @Published ιδιότητας μέσα στο αντικείμενο.

Σύμφωνα με το βιβλίο του Matt Neuburg «IOS 18 Programming Fundamentals with Swift» (2025), το @Published είναι ένα βολικό περιτύλιγμα γύρω από το pattern willSet, που καλεί αυτόματα το objectWillChange.send(). Ο μεταγλωττιστής ξετυλίγει το @Published σε μια υπολογισμένη ιδιότητα με έναν willSet παρατηρητή, που παρέχει μηδενικό κόστος κατά τη λειτουργία σε σύγκριση με την χειροκίνητη υλοποίηση.

Χρησιμοποιείτε το @Published για όλες τις ιδιότητες ObservableObject των οποίων οι αλλαγές πρέπει να αντικατοπτρίζονται στη διεπαφή. Για ιδιότητες που δεν επηρεάζουν το UI, οι συνηθισμένες stored properties χωρίς @Published μειώνουν τον αριθμό των μη απαραίτητων ξανασχεδιάσεων.

Πώς λειτουργεί το @Published

@Published δημιουργεί δύο κλειδιά στοιχεία κατά τη μεταγλώττιση. Πρώτο — μια αποθηκευμένη ιδιότητα με έναν willSet παρατηρητή που καλεί το objectWillChange.send() πριν από την εγγραφή της νέας τιμής. Δεύτερο — η προβολή $propertyName που επιστρέφει έναν Published.Publisher που μπορεί να χρησιμοποιηθεί απευθείας σε pipeline του Combine.

Θεωρήστε την κλάση Settings με τρεις ιδιότητες: δύο @Published και μία συνηθισμένη:

swift
class Settings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isDarkMode = false
    var lastLogin: Date = Date()  // χωρίς @Published
}

Κατά την αλλαγή του username ή του isDarkMode, το SwiftUI σχεδιάζει ξανά όλες τις προβολές που είναι εγγεγραμμένες στην επίπεδη Settings. Η αλλαγή του lastLogin δεν θα προκαλέσει ξανασχεδίασμα. Αν χρειάζεται να ειδοποιήσετε με χείρα τους συνδρομητές για την αλλαγή μιας συνηθισμένης ιδιότητας, μπορείτε να καλέσετε το objectWillChange.send() στον παρατηρητή willSet.

Μια σημαντική λεπτομέρεια: το @Published δημοσιεύει αλλαγές μόνο κατά την άμεση εγγραφή στην ιδιότητα. Αν η ιδιότητα είναι τύπου αναφοράς (κλάση) και η εσωτερική κατάστασή της αλλάζει χωρίς να αντικατασταθεί η αναφορά, το @Published δεν θα το ανιχνεύσει. Σε τέτοιες περιπτώσεις, απαιτείται με χείρα αποστολή του συμβάντος ή αντικατάσταση με έναν τύπο τιμής (struct).

@Published και Combine

@Published είναι σχεδόν ενσωματωμένο με το Combine — κάθε @Published ιδιότητα παρέχει αυτόματα έναν publisher προσβάσιμο μέσω της προβολής $propertyName. Αυτό επιτρέπει την εφαρμογή τελεστών Combine για φιλτράρισμα, μετασχηματισμό, συνδυασμό και καθυστερημένη επεξεργασία τιμών.

Ένα τυπικό σενάριο — αναζήτηση με debounce. Το πεδίο εισαγωγής είναι συνδεδεμένο με την @Published ιδιότητα searchText, αλλά το αίτημα προς τον εξυπηρετητή πρέπει να σταλεί μόνο μετά από μια παύση 300 ms. Το Combine με $searchText.debounce το λύνει σε μία γραμμή:

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 (Swift by Sundell, 2024), ο συνδυασμός του @Published με το Combine είναι ένα τυπικό pattern για αντιδραστικά pipeline σε εφαρμογές SwiftUI: validation, debounce, throttle, combineLatest, merge με άλλους publishers. Το @Published λειτουργεί ως γέφυρα μεταξύ του επιτακτικού UI κώδικα και του αντιδραστικού Combine.

@Published συγκριτικά με το μακρο @Observable

Με την κυκλοφορία του iOS 17, η Apple εισήγαγε το μακρο @Observable, που προσφέρει μια εναλλακτική προσέγγιση στην αντιδραστικότητα χωρίς ObservableObject και @Published. Το @Observable παρακολουθεί αυτόματα την πρόσβαση σε ιδιότητες σε επίπεδο ανάγνωσης, όχι εγγραφής, που παρέχει πιο ακριβή ξανασχεδίαση — ενημερώνεται μόνο η προβολή που διαβάζει την συγκεκριμένη ιδιότητα που αλλάχθηκε.

Αυτό δεν σημαίνει όμως ότι το @Published έχει απαρχαιωθεί. Το @Published παραμένει απαραίτητο όταν χρειάζεται ενσωμάτωση με τα pipeline του Combine — η προβολή $propertyName παρέχει έναν publisher που δεν έχει το @Observable. Επιπλέον, για συμβατότητα προς τα πίσω με iOS 16 και παλαιότερα, το @Published+ObservableObject είναι η μοναδική επιλογή. Σύμφωνα με τη συνεδρία Apple WWDC 2023 «Discover Observation in SwiftUI», η Apple συνιστά το @Observable για νέα έργα, αλλά διατηρεί ρητά την υποστήριξη για το @Published για υπάρχοντα κώδικα και σενάρια Combine.

Στην πράξη, πολλά έργα χρησιμοποιούν μια υβριδική προσέγγιση: νέα μοντέλα δεδομένων γράφονται με @Observable, ενώ τα υπάρχοντα ObservableObject με @Published παραμένουν χωρίς αναπροσαρμογή. Το @Published είναι επίσης ανικατάστατο όταν απαιτείται ακριβής έλεγχος πάνω στη δημοσίευση — για παράδειγμα, καθυστέρηση της ειδοποίησης έως την ολοκλήρωση της μαζικής ενημέρωσης πολλών ιδιοτήτων.

Συνηθισμένα λάθη με το @Published

Πρώτο λάθος — εφαρμογή του @Published σε struct. Ο μεταγλωττιστής θα εμφανίσει σφάλμα: «Property wrapper cannot be applied to a computed property» ή «'@Published' is only available on members of a class». Το @Published απαιτεί σημασιολογία αναφοράς, διότι το ObservableObjectPublisher είναι μια κλάση που πρέπει να είναι μοναδική για κάθε στοιχείο.

Δεύτερο λάθος — μεταβολή του περιεχομένου μιας ιδιότητας αναφοράς χωρίς την αντικατάσταση της αναφοράς. Αν μια @Published ιδιότητα έχει τύπο πίνακα [String] και καλέσετε array.append("new"), το @Published δεν θα ανιχνεύσει την αλλαγή επειδή η αναφορά στον πίνακα δεν έχει αλλάξει. Λύση: εκχωρήστε νέα τιμή στην ιδιότητα array = array + ["new"] ή χρησιμοποιήστε με χείρα το objectWillChange.send().

Τρίτο λάθος — υπερβολικός αριθμός @Published ιδιοτήτων. Κάθε @Published ιδιότητα προκαλεί το ξανασχεδίασμα όλων των προβολών που είναι εγγεγραμμένες στο ObservableObject, όχι μόνο αυτών που διαβάζουν αυτή την ιδιότητα. Σύμφωνα με το Point-Free (2025), η διαίρεση ενός μεγάλου ObservableObject σε πολλά μικρά με @StateObject και @EnvironmentObject μειώνει τον αριθμό των μη απαραίτητων ξανασχεδιάσεων και βελτιώνει την απόδοση.

Παραδείγματα κώδικα

Πρώτο παράδειγμα — ViewModel φόρμας εγγραφής με επικύρωση. Οι @Published ιδιότητες email και password πυροδοτούν την εμφάνιση σφαλμάτων επικύρωσης μέσω του pipeline Combine:

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

Δεύτερο παράδειγμα — με χείρα δημοσίευση για συλλογή στοιχείων αναφοράς. Αντί να αντικαθιστάτε ολόκληρο τον πίνακα σε κάθε αλλαγή μέσα σε ένα στοιχείο, χρησιμοποιείται το 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()  // με χείρα ειδοποίηση
    }
}

Τρίτο παράδειγμα — Assign σε @Published ιδιότητα μέσω Combine. Χρησιμοποιώντας τη νέα σύνταξη Swift 5.9, μπορείτε να εκχωρήσετε απευθείας μέσω της προβολής assign(to: &$property) χωρίς Optional περιτύλιγμα. Αυτός είναι ο συντομότερος τρόπος να συνδέσετε έναν publisher με @Published ιδιότητα χωρίς να δημιουργήσετε συνδρομή.

Συχνές Ερωτήσεις

Μπορεί να χρησιμοποιηθεί το @Published σε struct;

Όχι, το @Published μπορεί να εφαρμοστεί μόνο εντός κλάσης που συμμορφώνεται με το ObservableObject. Σε struct χρησιμοποιείτε @State για τοπική κατάσταση ή @Bindable με το μακρο @Observable σε iOS 17+. Η προσπάθεια εφαρμογής @Published σε struct θα προκαλέσει σφάλμα μεταγλώττισης.

Πώς λειτουργεί το @Published με πίνακες και λεξικά;

Σωστά: εκχωρήστε μια νέα τιμή στο σύνολό της (array = array + ["new"]). Το @Published παρακολουθεί την αντικατάσταση της αναφοράς, όχι τη μεταβολή του περιεχομένου. Για συλλογές αναφορών, χρησιμοποιείτε με χείρα το objectWillChange.send() μετά από μεταβολή της εσωτερικής κατάστασης των στοιχείων.

Σε τι διαφέρει το @Published από το @State;

@State προορίζεται για τοπική κατάσταση εντός μιας προβολής και λειτουργεί μόνο με τύπους τιμής. Το @Published — για ObservableObject ιδιότητες που μπορούν να διαβαστούν από πολλές προβολές μέσω @ObservedObject ή @EnvironmentObject. Το @State είναι απλούστερο, το @Published είναι ισχυρότερο χάρη στην ενσωμάτωση με το Combine.

Είναι απαραίτητο το @Published για κάθε ObservableObject ιδιότητα;

Μόνο για αυτές που οι αλλαγές τους πρέπει να ενημερώνουν το UI. Οι ιδιότητες για εσωτερικούς υπολογισμούς, προσωρινή αποθήκευση ή προσωρινές σημαίες δεν απαιτούν @Published — αυτό μειώνει τον αριθμό των μη απαραίτητων ξανασχεδιάσεων. Χρησιμοποιείτε το @Published ως σήμα ότι “αυτή η ιδιότητα είναι σημαντική για τη διεπαφή”.

Πώς λειτουργεί το @Published με το Core Data;

Το SwiftUI ενσωματώνεται με το Core Data μέσω @FetchRequest και @ObservedObject για NSManagedObject. Το ManagedObject ήδη συμμορφώνεται με το ObservableObject, επομένως δεν απαιτείται @Published — το NSManagedObject ενημερώνει αυτόματα για αλλαγές. Το @Published χρησιμοποιείται στο επίπεδο ViewModel μεταξύ Core Data και UI για μετασχηματισμό δεδομένων.

Συμπεράσματα

  • @Published — property wrapper από το Combine, δημοσιεύει αυτόματα τις αλλαγές ObservableObject ιδιοτήτων για SwiftUI και pipeline Combine
  • Μηχανισμός: ο willSet παρατηρητής καλεί το objectWillChange.send(), δημιουργώντας publisher μέσω της προβολής $property
  • Combine: το @Published παρέχει publisher για debounce, map, combineLatest και άλλους τελεστές — είναι η γέφυρα μεταξύ UI και αντιδραστικών pipeline
  • @Observable (iOS 17+) — εναλλακτική για νέα έργα, αλλά το @Published παραμένει το πρότυπο για Combine και συμβατότητα προς τα πίσω
  • Λάθη: το @Published δεν λειτουργεί σε struct, δεν παρακολουθεί μεταβολή αναφορών, υπερβολικός @Published αυξάνει τις ξανασχεδιάσεις
  • Best practice: σημειώστε μόνο ιδιότητες που επηρεάζουν το UI με @Published, χωρίστε μεγάλα ObservableObject σε πολλά μικρά
  • Assign: assign(to: &$property) στο Swift 5.9 επιτρέπει την απευθεία εγγραφή του publisher σε @Published ιδιότητα

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης