RxSwift — τι είναι, βασικές έννοιες και αντιδραστικός προγραμματισμός

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

Το RxSwift είναι μια βιβλιοθήκη αντιδραστικού προγραμματισμού για Swift που υλοποιεί το μοτίβο Observable. Σύμφωνα με τα δεδομένα του ReactiveX, 2025, είναι η πιο δημοφιλής υλοποίηση των Reactive Extensions για το οικοσύστημα της Apple. Το Observable λειτουργεί ως πηγή συμβάντων και ο Observer εγγράφεται για να τα λαμβάνει.

Κύρια σημεία

  • RxSwift — υλοποίηση των Reactive Extensions για Swift με υποστήριξη Observable, Subject και 300+ τελεστών
  • Observable — πηγή συμβάντων που εκπέμπει τιμές, σφάλματα ή σήμα ολοκλήρωσης
  • Subject — ταυτόχρονα Observable και Observer, επιτρέπει τη μη αυτόματη εισαγωγή συμβάντων στη ροή
  • DisposeBag — μηχανισμός αυτόματης διαχείρισης μνήμης που ακυρώνει τις εγγραφές κατά την αποδέσμευση
  • Schedulers — διαχειρίζονται νήματα εκτέλεσης, επιτρέποντας εναλλαγή μεταξύ main και background ουρών

Τι είναι το RxSwift;

Το RxSwift είναι μια βιβλιοθήκη αντιδραστικού προγραμματισμού για τη γλώσσα Swift, μεταφερμένη από το Reactive Extensions (Rx). Επιτρέπει την περιγραφή ασύγχρονων και βασισμένων σε συμβάντα προγραμμάτων μέσω του Observable Sequence — μιας ακολουθίας δεδομένων διαθέσιμων στο χρόνο. Οι προγραμματιστές iOS χρησιμοποιούν το RxSwift για το χειρισμό αιτημάτων δικτύου, συμβάντων UI και δεδομένων ροής χωρίς ένθετες callback.

Observable και Observer

Τη βάση του RxSwift αποτελούν δύο βασικά πρωτόκολλα: ObservableType — η πηγή συμβάντων που μπορεί να εκπέμψει τρεις τύπους σημάτων: .next(value), .error(error) και .completed. Ο Observer εγγράφεται στο Observable μέσω της μεθόδου subscribe και λαμβάνει αυτά τα συμβάντα. Αυτό το μοντέλο ονομάζεται Reactive Streams και εγγυάται ότι κανένα συμβάν δεν θα χαθεί με σωστή εγγραφή.

Τελεστές μετασχηματισμού

Το RxSwift παρέχει πάνω από 300 τελεστές για εργασία με ροές: ο map μετασχηματίζει κάθε συμβάν, ο filter επιτρέπει μόνο τα κατάλληλα, ο flatMap αναπτύσσει ένθετα Observable σε μία ενιαία ροή. Οι τελεστές συνδυάζονται σε αλυσίδες, δημιουργώντας έναν δηλωτικό αγωγό επεξεργασίας δεδομένων χωρίς παρενέργειες.

Traits: Single, Completable, Maybe

Εκτός από το βασικό Observable, το RxSwift παρέχει εξειδικευμένους τύπους περιτυλίγματος. Το Single εκπέμπει ακριβώς μία τιμή ή σφάλμα — ιδανικό για αιτήματα HTTP. Το Completable τελειώνει με επιτυχία ή σφάλμα χωρίς τιμή — για λειτουργίες εγγραφής. Το Maybe συνδυάζει και τα δύο σενάρια: μπορεί να τελειώσει με τιμή, χωρίς τιμή ή με σφάλμα. Αυτά τα Traits απλοποιούν τη σημασιολογία και καθιστούν τον κώδικα αυτο-τεκμηριωμένο.

Πώς λειτουργεί ο αντιδραστικός προγραμματισμός στο RxSwift

Ο αντιδραστικός προγραμματισμός στο RxSwift βασίζεται στο μοτίβο Observer. Το ObservableSequence είναι το ανάλογο του Sequence από την τυπική βιβλιοθήκη, αλλά με ασύγχρονη πρόσβαση σε στοιχεία. Η ροή συμβάντων μεταδίδεται μέσω μιας αλυσίδας τελεστών, καθένας από τους οποίους επιστρέφει ένα νέο ObservableSequence χωρίς να μεταλλάσσει το αρχικό.

Αλυσίδες τελεστών

Οι τελεστές στο RxSwift είναι καθαρές συναρτήσεις που δέχονται ένα ObservableSequence και επιστρέφουν ένα νέο. Για παράδειγμα, ο map δημιουργεί μια νέα ακολουθία εφαρμόζοντας μετασχηματισμό σε κάθε στοιχείο. Συνδυάζοντας τελεστές, ο προγραμματιστής χτίζει έναν αγωγό όπου τα δεδομένα περνούν από όλα τα στάδια επεξεργασίας χωρίς ενδιάμεσες μεταβλητές.

Schedulers και νήματα εκτέλεσης

Οι Schedulers είναι μια αφαίρεση πάνω από τα νήματα εκτέλεσης στο RxSwift. Ο Scheduler καθορίζει σε ποιο νήμα θα εκτελεστεί ο κώδικας: MainScheduler — νήμα UI, SerialDispatchQueueScheduler — ουρά παρασκηνίου. Οι τελεστές subscribeOn και observeOn καθορίζουν πού γίνεται η εργασία και πού επεξεργάζονται τα αποτελέσματα.

Βασικά στοιχεία του RxSwift

Το RxSwift περιλαμβάνει διάφορους βασικούς τύπους, καθένας από τους οποίους λύνει τη δική του εργασία στον αντιδραστικό αγωγό. Το Single — Observable που εκπέμπει ακριβώς μία τιμή ή σφάλμα, βολικό για αιτήματα δικτύου. Το Completable τελειώνει με επιτυχία ή σφάλμα χωρίς τιμή. Το Maybe συνδυάζει ιδιότητες των Single και Completable.

Subject και Relay

Το Subject είναι ένα καυτό Observable που ταυτόχρονα λειτουργεί ως Observer. Το PublishSubject εκπέμπει μόνο νέα συμβάντα στους συνδρομητές, το BehaviorSubject — το τελευταίο συμβάν συν τα νέα. Το Relay είναι μια παραλλαγή του Subject που δεν εκπέμπει .error ή .completed, εγγυώμενο τη συνέχεια της ροής. Το BehaviorRelay αποθηκεύει την τρέχουσα τιμή και είναι κατάλληλο για State-driven UI.

DisposeBag

Το DisposeBag είναι μια συλλογή Disposable που ακυρώνει αυτόματα όλες τις εγγραφές κατά την αποδέσμευσή του. Στο iOS, το DisposeBag συνήθως προστίθεται στο UIViewController ή UIView. Κατά το κλείσιμο της οθόνης, το DisposeBag καθαρίζεται — αυτό αποτρέπει διαρροές μνήμης και αναφορές σε ανύπαρκτα στοιχεία UI.

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

Παρακάτω εμφανίζεται ένα παράδειγμα δημιουργίας Observable από έναν πίνακα δεδομένων χρησιμοποιώντας τον τελεστή map για μετασχηματισμό συμβολοσειρών:

swift
let observable = Observable.of("Swift", "RxSwift", "Reactive")

observable
    .map { $0.uppercased() }
    .subscribe(onNext: { value in
        print("Λήφθηκε: \(value)")
    })
    .disposed(by: disposeBag)

Στο δεύτερο παράδειγμα παρουσιάζεται ο συνδυασμός δύο αιτημάτων δικτύου με τη βοήθεια του zip — ο τελεστής περιμένει και τα δύο Observable να εκπέμψουν τιμή και συνδυάζει τα αποτελέσματα σε μια πλειάδα:

swift
let first = fetchUser(id: "123")
let second = fetchPosts(userId: "123")

Observable
    .zip(first, second)
    .observe(on: MainScheduler.instance)
    .subscribe(onNext: { user, posts in
        updateUI(user: user, posts: posts)
    })
    .disposed(by: disposeBag)

Το τρίτο παράδειγμα δείχνει τη χρήση του BehaviorRelay για αποθήκευση κατάστασης και αυτόματη ενημέρωση του UI σε αλλαγές: κάθε αλλαγή state.accept() μεταδίδεται αμέσως στους συνδρομητές, που είναι ιδανικό για μοτίβα State στην αρχιτεκτονική MVVM.

swift
let state = BehaviorRelay(value: "idle")

state
    .subscribe(onNext: { status in
        print("Κατάσταση: \(status)")
    })
    .disposed(by: disposeBag)

state.accept("loading") // Θα εμφανίσει: Κατάσταση: loading

RxSwift έναντι άλλων προσεγγίσεων

Το RxSwift διαφέρει από τις παραδοσιακές μεθόδους ασύγχρονου προγραμματισμού (Delegation, NotificationCenter, Callback) ως προς τη δηλωτικότητα και τη συνθεσιμότητα. Σε αντίθεση με το Combine, το RxSwift υποστηρίζει iOS 9+ και έχει περισσότερους τελεστές. Ωστόσο, το Combine είναι ενσωματωμένο στο Foundation και το SwiftUI σε επίπεδο γλώσσας, που του δίνει πλεονέκτημα σε νέα έργα Apple.

Το κύριο πλεονέκτημα του RxSwift έναντι του GCD (Grand Central Dispatch) — η δυνατότητα συνδυασμού και μετασχηματισμού ροών δεδομένων σε επίπεδο αφαίρεσης, αντί για χειροκίνητη διαχείριση ουρών. Ταυτόχρονα, το RxSwift απαιτεί εκμάθηση των εννοιών της αντιδραστικής προσέγγισης, που αυξάνει το κατώφλι εισόδου για την ομάδα.

Στην πράξη, το RxSwift χρησιμοποιείται σε μεγάλα έργα όπου οι αντιδραστικές αλυσίδες συνδέουν συμβάντα UI, επιχειρηματική λογική και αλληλεπιδράσεις δικτύου σε έναν ενιαίο αγωγό. Για παράδειγμα, σε εφαρμογές συναλλαγών, οι ροές τιμών επεξεργάζονται μέσω RxSwift: τα ticks έρχονται από WebSocket, περνούν από φιλτράρισμα, ομαδοποιούνται ανά χρονικό πλαίσιο και εμφανίζονται στο γράφημα σε πραγματικό χρόνο. Ένα τέτοιο σενάριο είναι δύσκολο να υλοποιηθεί μέσω Delegation ή NotificationCenter χωρίς απώλεια αναγνωσιμότητας.

Εναλλακτικές λύσεις για το RxSwift περιλαμβάνουν το Combine (iOS 13+), το AsyncSequence από το Swift Concurrency (iOS 15+), καθώς και τη βιβλιοθήκη ReactiveSwift χωρίς δέσμευση σε πλατφόρμες Apple. Η επιλογή εξαρτάται από την ελάχιστη υποστηριζόμενη έκδοση iOS και την εμπειρία των προγραμματιστών. Για νέα έργα iOS 15+, οι ομάδες συχνά επιλέγουν το AsyncSequence — δεν απαιτεί εγκατάσταση βιβλιοθήκης και χρησιμοποιεί εγγενείς κατασκευές της γλώσσας Swift.

Τα αρχιτεκτονικά μοτίβα με RxSwift συνήθως ακολουθούν MVVM ή Clean Architecture. Το ViewModel περιέχει όλη την επιχειρηματική λογική με τη μορφή αλυσίδων Observable, το View εγγράφεται στα μετασχηματισμένα δεδομένα. Το μοτίβο Input-Output διαχωρίζει τα συμβάντα εισόδου (αφές, εισαγωγή κειμένου) και τις καταστάσεις εξόδου (κείμενο κουμπιού, ορατότητα loader). Αυτή η προσέγγιση απλοποιεί τη δοκιμή: το ViewModel δοκιμάζεται χωρίς UI μέσω εικονικών Scheduler.

Το RxSwift είναι κατάλληλο τόσο για μικρά έργα με λίγες οθόνες όσο και για μεγάλες επιχειρηματικές εφαρμογές με δεκάδες αρθρώματα. Σε μεγάλα έργα, οι αντιδραστικές αλυσίδες διαπερνούν ολόκληρη την αρχιτεκτονική: από την παρατήρηση UserDefaults μέσω RxProperty έως αιτήματα δικτύου μέσω Moya (περιτύλιγμα RxSwift πάνω από Alamofire). Κάθε άρθρωμα είναι απομονωμένο και επικοινωνεί μέσω αντιδραστικών διεπαφών, που απλοποιεί την αντικατάσταση υλοποίησης χωρίς αλλαγή συνδρομητών. Με σωστή αρχιτεκτονική, το RxSwift μειώνει τον όγκο κώδικα σε σύγκριση με κλασικές προσεγγίσεις, καθώς δεν χρειάζεται να γραφτεί boilerplate για KVO, Target-Action ή NotificationCenter.

Το RxSwift χρησιμοποιείται ενεργά σε έργα με RxDataSources — μια βιβλιοθήκη για αντιδραστική εργασία με UITableView και UICollectionView. Το RxDataSources υπολογίζει αυτόματα τη διαφορά μεταξύ παλιού και νέου συνόλου κελιών και εφαρμόζει κινούμενες αλλαγές. Αυτό απαλλάσσει τον προγραμματιστή από χειροκίνητη εργασία με beginUpdates/endUpdates και εξαλείφει crashes σε περίπτωση ασυμφωνίας δεδομένων.

Για τον εντοπισμό σφαλμάτων σε αλυσίδες RxSwift υπάρχει ο τελεστής debug() — καταγράφει όλα τα συμβάντα: subscribe, next, error, completed, dispose. Είναι απαραίτητο εργαλείο στην ανάπτυξη σύνθετων αντιδραστικών αγωγών. Το debug(String) δέχεται ένα αναγνωριστικό που εμφανίζεται στα αρχεία καταγραφής. Για προφίλ μνήμης, το RxSwift.Resources.total δείχνει τον συνολικό αριθμό ενεργών Observable και Disposable στην εφαρμογή — βοηθά στον εντοπισμό διαρροών όταν το DisposeBag δεν έχει καθαριστεί ή ένα retain cycle διατηρεί μια εγγραφή. Ο πρόσθετος τελεστής takeUntil(self.rx.deallocated) ακυρώνει αυτόματα την εγγραφή κατά την αποδέσμευση του αντικειμένου — αυτό είναι ένα ακόμα επίπεδο προστασίας από διαρροές.

Βέλτιστες πρακτικές RxSwift

Κατά τη σύνταξη κώδικα RxSwift είναι σημαντικό να τηρείται η αρχή ένα Observable ανά εγγραφή: κάθε ViewController δεν πρέπει να δημιουργεί περισσότερες από μία εγγραφές σε ένα Observable — αυτό μειώνει τον κίνδυνο race condition. Για απομνημόνευση Observable χρησιμοποιείται ο τελεστής share(), ο οποίος μετατρέπει ένα κρύο Observable σε καυτό με buffer επανάληψης μεγέθους 1. Κατά την εργασία με κοινόχρηστους πόρους, χρησιμοποιήστε connect() για διαχείριση της έναρξης εκπομπής — αυτό εγγυάται ότι όλοι οι συνδρομητές συνδέονται πριν από το πρώτο συμβάν.

Η δοκιμή κώδικα RxSwift εκτελείται μέσω του TestScheduler — ενός εικονικού Scheduler που επιτρέπει τη διαχείριση χρόνου. Το testScheduler.createHotObservable(values) δημιουργεί ένα Observable με προκαθορισμένη ακολουθία συμβάντων σύμφωνα με εικονικό χρόνο. Το testScheduler.start() ξεκινά την επεξεργασία. Το TestScheduler επιτρέπει τον έλεγχο της σειράς και της εικονικής χρονικής σήμανσης των συμβάντων χωρίς πραγματικές καθυστερήσεις, καθιστώντας τις δοκιμές γρήγορες και ντετερμινιστικές.

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

Ποια είναι η διαφορά μεταξύ Observable και Subject στο RxSwift;

Το Observable είναι μια κρύα πηγή: δεν εκπέμπει συμβάντα μέχρι την εγγραφή. Το Subject είναι καυτό: εκπέμπει συμβάντα ανεξάρτητα από συνδρομητές και επιτρέπει μη αυτόματη εισαγωγή τιμών μέσω onNext. Το PublishSubject μεταδίδει μόνο νέα συμβάντα, το BehaviorSubject — το τελευταίο συν τα νέα.

Πώς το DisposeBag αποτρέπει διαρροές μνήμης στο RxSwift;

Το DisposeBag αποθηκεύει όλες τις Disposable εγγραφές. Όταν το DisposeBag αποδεσμεύεται (για παράδειγμα, κατά το κλείσιμο ViewController), όλες οι αποθηκευμένες εγγραφές ακυρώνονται αυτόματα. Αυτό εγγυάται ότι το Observable δεν θα στείλει πλέον συμβάν σε ένα ήδη κατεστραμμένο αντικείμενο UI.

Τι να επιλέξω: RxSwift ή Combine σε νέο έργο iOS;

Εάν η ελάχιστη έκδοση iOS είναι 13+ και η ομάδα γνωρίζει SwiftUI — επιλέξτε Combine. Εάν το έργο υποστηρίζει iOS 12 και κάτω ή απαιτεί μεγαλύτερο σύνολο τελεστών — RxSwift. Το Combine παρέχει καλύτερη ενσωμάτωση με το Foundation (URLSession, Timer, NotificationCenter).

Πώς λειτουργούν οι Schedulers στο RxSwift;

Οι Schedulers αφαιρούν τα νήματα εκτέλεσης. Το subscribeOn υποδεικνύει σε ποιο Scheduler εκτελείται η εγγραφή (συνήθως background). Το observeOn καθορίζει σε ποιο Scheduler λαμβάνονται τα συμβάντα (συχνότερα MainScheduler για ενημερώσεις UI). Το SerialDispatchQueueScheduler λειτουργεί μέσω GCD.

Μπορεί το RxSwift να χρησιμοποιηθεί με SwiftUI;

Ναι, το RxSwift μπορεί να ενσωματωθεί με SwiftUI μέσω ObservableObject. Χρησιμοποιήστε το BehaviorRelay ως ιδιότητες @Published: η εγγραφή στο Relay μεταδίδει αλλαγές στο Combine και το SwiftUI επανασχεδιάζει το View μέσω @ObservedObject. Αυτό είναι ένα δημοφιλές μοτίβο μετάβασης από UIKit σε SwiftUI.

Σύνοψη

  • RxSwift — βιβλιοθήκη αντιδραστικού προγραμματισμού βασισμένη στα Reactive Extensions και το μοτίβο Observable
  • Observable εκπέμπει τρεις τύπους σημάτων: .next, .error και .completed
  • Subject (PublishSubject, BehaviorSubject) συνδυάζει Observable και Observer για καυτές ροές
  • DisposeBag διαχειρίζεται τον κύκλο ζωής εγγραφών και αποτρέπει διαρροές μνήμης
  • Τελεστές (map, filter, flatMap, zip) επιτρέπουν τη δημιουργία δηλωτικών αλυσίδων επεξεργασίας
  • Schedulers εναλλάσσουν εκτέλεση μεταξύ ουρών παρασκηνίου και νήματος UI
  • Για νέα ανάπτυξη σε iOS 13+, εξετάστε το Combine ως ενσωματωμένη εναλλακτική

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

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

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

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