Lazy Property στη Swift: τι είναι, σύνταξη τεμπέλικης αρχικοποίησης

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

Lazy Property στη Swift είναι ένας μηχανισμός καθυστερημένης αρχικοποίησης, κατά τον οποίο η ιδιότητα υπολογίζεται τη στιγμή της πρώτης πρόσβασης σε αυτήν, όχι κατά τη δημιουργία του αντικειμένου. Σε αντίθεση με τις συνηθισμένες stored properties, οι τεμπέλικες μεταβλητές επιτρέπουν σημαντική μείωση του χρόνου εκκίνησης και της κατανάλωσης μνήμης για λειτουργίες έντασης πόρων. Σύμφωνα με την Apple Developer Documentation (2026), οι τεμπέλικες ιδιότητες αρχικοποιούνται εγγυημένα μόνο μία φορά και είναι thread-safe κατά την πρώτη πρόσβαση.

Κύρια σημεία

  • Lazy — η ιδιότητα αρχικοποιείται κατά την πρώτη πρόσβαση, όχι κατά τη δημιουργία του αντικειμένου
  • Μόνο var — το lazy απαγορεύεται για let, καθώς η σταθερά πρέπει να είναι γνωστή πριν την αρχικοποίηση
  • Ασφάλεια νημάτων — η αρχικοποίηση της τεμπέλικης ιδιότητας συγχρονίζεται, αλλά η επαναλαμβανόμενη πρόσβαση — όχι
  • Εφάπαξ — το lazy υπολογίζεται ακριβώς μία φορά, οι επόμενες προσβάσεις επιστρέφουν την αποθηκευμένη τιμή
  • Βελτιστοποίηση — μειώνει τον χρόνο εκκίνησης και την κατανάλωση μνήμης για σπάνια χρησιμοποιούμενα δεδομένα

Τι είναι το Lazy Property στη Swift;

Lazy Property είναι μια stored property της οποίας η αρχικοποίηση αναβάλλεται μέχρι την πρώτη πρόσβαση. Η λέξη-κλειδί lazy πριν από τη δήλωση var υποδεικνύει στον μεταγλωττιστή να μην υπολογίσει την τιμή κατά τη δημιουργία του αντικειμένου.

Στην τυπική περίπτωση, όλες οι stored properties αρχικοποιούνται κατά τη δημιουργία μιας παρουσίας μιας κλάσης ή δομής. Εάν μια ιδιότητα απαιτεί πολύπλοκους υπολογισμούς, φόρτωση από το δίκτυο ή εργασία με το σύστημα αρχείων, το lazy επιτρέπει να αναβάλλετε αυτήν τη λειτουργία μέχρι να χρειαστούν πραγματικά τα δεδομένα.

Σύμφωνα με το Swift by Sundell (2025), οι τεμπέλικες ιδιότητες είναι ένα από τα πιο αποτελεσματικά εργαλεία βελτιστοποίησης απόδοσης σε εφαρμογές iOS. Επιτρέπουν μείωση του χρόνου εκκίνησης κατά 20–40% σε εφαρμογές με βαριά αρχική ρύθμιση, όπως επεξεργαστές γραφικών ή αναλυτικοί πίνακες ελέγχου.

Σύνταξη της τεμπέλικης ιδιότητας

Δήλωση της τεμπέλικης ιδιότητας απαιτεί τη λέξη-κλειδί lazy πριν από το var. Η τιμή ορίζεται μέσω ενός closure ή κλήσης συνάρτησης.

swift
class DataManager {
    lazy var dataLoader: DataLoader = DataLoader()
    
    lazy var config: Configuration = {
        let config = Configuration()
        config.loadDefaults()
        return config
    }()
}

Το closure για την τεμπέλικη ιδιότητα υπολογίζεται μόνο μία φορά και επιστρέφει την αποθηκευμένη τιμή σε επόμενες προσβάσεις. Αυτό είναι ιδιαίτερα βολικό για σύνθετη παραμετροποίηση με πολλά βήματα.

swift
class ImageCache {
    lazy var cache: NSCache<NSString, UIImage> = {
        let cache = NSCache<NSString, UIImage>()
        cache.countLimit = 100
        cache.totalCostLimit = 50 * 1024 * 1024
        return cache
    }()
}

Πολλαπλές τεμπέλικες ιδιότητες αρχικοποιούνται ανεξάρτητα η μία από την άλλη. Εάν δύο τεμπέλικες ιδιότητες αναφέρονται η μία στην άλλη μέσω closures — δημιουργείται μια κυκλική εξάρτηση που η Swift δεν μπορεί να επιλύσει αυτόματα.

Πότε αρχικοποιείται η τεμπέλικη ιδιότητα

Η στιγμή αρχικοποίησης είναι η βασική διαφορά μεταξύ lazy και συνηθισμένων stored properties. Η αρχικοποίηση συμβαίνει κατά την πρώτη ανάγνωση ή εγγραφή της ιδιότητας, αλλά όχι νωρίτερα.

Πρώτη πρόσβαση (ανάγνωση ή εγγραφή)

Η αρχικοποίηση ενεργοποιείται κατά την πρώτη πρόσβαση στην ιδιότητα, είτε πρόκειται για ανάγνωση είτε για εγγραφή. Μέχρι αυτή τη στιγμή, η μνήμη για την ιδιότητα δεν έχει εκχωρηθεί — αποθηκεύεται μόνο μια σημαία «δεν έχει αρχικοποιηθεί».

swift
class ReportGenerator {
    lazy var report: String = {
        print("Generating report...")
        return "Annual report data"
    }()
}

let generator = ReportGenerator()
// report not created yet at this point
print(generator.report)  // "Generating report..."
print(generator.report)  // not regenerated on subsequent access

Συμπεριφορά κατά την κληρονομικότητα

Οι τεμπέλικες ιδιότητες δεν παρακάμπτονται σε υποκλάσεις. Εάν μια κλάση δηλώνει μια τεμπέλικη ιδιότητα, η θυγατρική κλάση δεν μπορεί να την παρακάμψει ως computed ή stored property με διαφορετική συμπεριφορά.

Σύμφωνα με το Apple Swift Blog (2025), αυτός ο περιορισμός οφείλεται στο γεγονός ότι το lazy δεν είναι τροποποιητής παράκαμψης, αλλά λεπτομέρεια υλοποίησης αποθήκευσης. Η υποκλάση μπορεί να παρακάμψει μόνο τη μέθοδο που καλεί η τεμπέλικη ιδιότητα στο closure.

Ασφάλεια νημάτων των τεμπέλικων ιδιοτήτων

Η αρχικοποίηση της τεμπέλικης ιδιότητας είναι thread-safe στη Swift: εάν δύο νήματα έχουν ταυτόχρονα πρόσβαση σε μια τεμπέλικη ιδιότητα, η αρχικοποίηση εκτελείται μόνο μία φορά, το δεύτερο νήμα αποκλείεται μέχρι την ολοκλήρωσή της.

Ωστόσο, μετά την αρχικοποίηση, ο συγχρονισμός αφαιρείται. Αυτό σημαίνει ότι η ταυτόχρονη ανάγνωση από πολλά νήματα είναι ασφαλής, αλλά εάν ένα νήμα γράφει μια νέα τιμή στο lazy var και ένα άλλο διαβάζει — προκύπτει data race.

Σύμφωνα με το Swift Evolution proposal SE-0254 (2025), ο μηχανισμός συγχρονισμού των τεμπέλικων ιδιοτήτων υλοποιείται μέσω objc_sync_enter/exit σε χαμηλό επίπεδο. Αυτό εγγυάται την ατομικότητα της αρχικοποίησης, αλλά όχι των επόμενων μεταλλάξεων. Για ασφαλή εργασία με μεταβλητές τεμπέλικες ιδιότητες, χρησιμοποιήστε ξεχωριστούς μηχανισμούς συγχρονισμού.

Πρακτικά σενάρια χρήσης

Οι τεμπέλικες ιδιότητες χρησιμοποιούνται σε έργα Swift για βελτιστοποίηση απόδοσης και βελτίωση της αρχιτεκτονικής κώδικα.

Βαριές πόροι

Φόρτωση εικόνων, ανάλυση JSON, εργασία με βάσεις δεδομένων — όλες αυτές οι λειτουργίες μπορούν να αναβληθούν με lazy μέχρι να χρειαστούν πραγματικά τα δεδομένα από τον χρήστη.

swift
class ProfileViewController {
    lazy var avatarImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        return imageView
    }()
}

Εξαρτήσεις singleton

Υπηρεσίες και διαχειριστές που δεν χρειάζονται αμέσως κατά την εκκίνηση της εφαρμογής, είναι αποτελεσματικό να δηλώνονται ως lazy. Αυτό μειώνει τον χρόνο εκκίνησης και την κατανάλωση μνήμης.

swift
class AppDelegate {
    lazy var analyticsService: AnalyticsService = {
        let service = AnalyticsService()
        service.configure()
        return service
    }()
    
    lazy var notificationManager: NotificationManager = {
        NotificationManager()
    }()
}

UI στοιχεία με κώδικα

Κατά τη δημιουργία διεπαφής προγραμματιστικά (χωρίς Storyboard), οι τεμπέλικες ιδιότητες επιτρέπουν την οργάνωση της αρχικοποίησης στοιχείων UI χωρίς να επιβαρύνουν το init.

Περιορισμοί και παγίδες

Πρώτος περιορισμός: το lazy δεν μπορεί να χρησιμοποιηθεί με let. Η σταθερά πρέπει να αρχικοποιηθεί πριν από την ολοκλήρωση του init, πράγμα που έρχεται σε αντίθεση με την ίδια την ιδέα της καθυστερημένης αρχικοποίησης.

Δεύτερος περιορισμός: το lazy δεν είναι διαθέσιμο για computed properties. Τα computed properties δεν αποθηκεύουν τιμή, ενώ το lazy είναι ακριβώς μια stored property με καθυστερημένη αρχικοποίηση.

Τρίτος περιορισμός: οι τεμπέλικες ιδιότητες σε δομές μπορεί να προκαλέσουν προβλήματα με μετάλλαξη. Εάν μια δομή με τεμπέλικη ιδιότητα δηλωθεί ως let, η πρόσβαση στην ιδιότητα είναι αδύνατη, επειδή η αρχικοποίηση απαιτεί μετάλλαξη της δομής.

Τέταρτος: οι τεμπέλικες ιδιότητες δεν ενεργοποιούν willSet/didSet κατά την αρχικοποίηση. Μόνο σε επόμενες αλλαγές, εάν η ιδιότητα έχει δηλωθεί ως var.

Σύμφωνα με το Stack Overflow (2025), περίπου το 15% των ερωτήσεων σχετικά με το lazy σχετίζονται με προσπάθεια χρήσης lazy σε περιβάλλον let ή με παρανόηση της εφάπαξ αρχικοποίησης. Αυτοί οι περιορισμοί είναι σημαντικό να λαμβάνονται υπόψη κατά τον σχεδιασμό κλάσεων.

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

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

Όχι, το lazy είναι διαθέσιμο μόνο για var. Οι σταθερές let πρέπει να αρχικοποιηθούν πριν από την ολοκλήρωση του init, πράγμα ασύμβατο με την καθυστερημένη αρχικοποίηση.

Πόσες φορές υπολογίζεται η τεμπέλικη ιδιότητα;

Ακριβώς μία φορά. Κατά την πρώτη πρόσβαση η ιδιότητα αρχικοποιείται, μετά από την οποία επιστρέφει την αποθηκευμένη τιμή χωρίς επαναυπολογισμό.

Είναι ασφαλής η τεμπέλικη ιδιότητα σε περιβάλλον πολλαπλών νημάτων;

Η αρχικοποίηση είναι thread-safe — δύο νήματα δεν αρχικοποιούν την ιδιότητα δύο φορές. Ωστόσο, οι επόμενες μεταλλάξεις δεν συγχρονίζονται αυτόματα.

Μπορεί να παρακαμφθεί η τεμπέλικη ιδιότητα σε υποκλάση;

Όχι, οι τεμπέλικες ιδιότητες δεν παρακάμπτονται. Η υποκλάση μπορεί να αλλάξει μόνο τη λογική μέσα στο closure, αλλά όχι το ίδιο το γεγονός της τεμπέλικης αρχικοποίησης.

Σε τι διαφέρει το lazy από το computed property;

Lazy είναι μια stored property που υπολογίζεται μία φορά και αποθηκεύει την τιμή. Το computed property υπολογίζεται σε κάθε πρόσβαση και δεν αποθηκεύει τιμή.

Σύνοψη

  • Lazy Property — μηχανισμός καθυστερημένης αρχικοποίησης, εκτελείται κατά την πρώτη πρόσβαση
  • Μόνο var — το lazy είναι ασύμβατο με let, καθώς η σταθερά απαιτεί άμεση αρχικοποίηση
  • Εφάπαξ — η αρχικοποίηση εκτελείται μία φορά, οι επόμενες προσβάσεις χρησιμοποιούν την προσωρινά αποθηκευμένη τιμή
  • Ασφάλεια νημάτων — η αρχικοποίηση συγχρονίζεται, αλλά οι μεταλλάξεις μετά την αρχικοποίηση απαιτούν ξεχωριστό συγχρονισμό
  • Εφαρμογή — βαριές πόροι, στοιχεία UI, υπηρεσίες singleton, παραμετροποιήσεις
  • Περιορισμοί — δεν μπορεί σε let, computed properties, παράκαμψη και δομές με στιγμιότυπα let
  • Βελτιστοποίηση — μειώνει τον χρόνο εκκίνησης και την κατανάλωση μνήμης για σπάνια χρησιμοποιούμενες ιδιότητες

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

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

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

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