Sobes.tech
Junior

Πού αποθηκεύονται οι τύποι δεδομένων στο Swift;

sobes.tech AI

Απάντηση από AI

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

Στοίβα

  • Τύποι τιμών (value types):
    • struct (δομές)
    • enum (περιγραφές)
    • Βασικοί τύποι, όπως Int, Double, Bool, String (μικρές συμβολοσειρές μπορούν να αποθηκευτούν απευθείας στη στοίβα για βελτιστοποίηση)
  • Τα δεδομένα αποθηκεύονται άμεσα στη στοίβα με την σειρά εκτέλεσης των συναρτήσεων.
  • Η κατανομή και η απελευθέρωση μνήμης γίνεται αυτόματα και πολύ γρήγορα (LIFO - Last In, First Out).

Σωρός

  • Τύποι αναφοράς (reference types):
    • class (κλάσεις)
    • Συναρτήσεις και closures
    • Αντικείμενα (AnyObject)
  • Τα αντικείμενα αποθηκεύονται στον σωρό, ενώ στη στοίβα υπάρχουν μόνο αναφορές σε αυτά.
  • Η κατανομή και η απελευθέρωση μνήμης στον σωρό γίνεται δυναμικά και διαχειρίζεται από το σύστημα (Automatic Reference Counting - ARC).
  • Η πρόσβαση στα δεδομένα στον σωρό είναι έμμεση, μέσω δείκτη.

Χαρακτηριστικά

  • Κατά την ανάθεση ενός τύπου τιμής, αντιγράφεται ολόκληρη η τιμή.
  • Κατά την ανάθεση ενός τύπου αναφοράς, αντιγράφεται μόνο η αναφορά, και και τα δύο αντικείμενα δείχνουν στην ίδια περιοχή μνήμης στον σωρό.
  • Το ARC παρακολουθεί τον αριθμό των ισχυρών αναφορών στα αντικείμενα στον σωρό και ελευθερώνει αυτόματα τη μνήμη όταν δεν υπάρχουν πλέον αναφορές.
// Παράδειγμα τύπου τιμής - αποθηκεύεται στη στοίβα
struct Point {
    var x: Int
    var y: Int
}

var p1 = Point(x: 10, y: 20)
var p2 = p1 // Αντιγράφεται ολόκληρη η τιμή

p2.x = 30 // Το p1 δεν αλλάζει
print("p1: \(p1), p2: \(p2)") // Έξοδος: p1: Point(x: 10, y: 20), p2: Point(x: 30, y: 20)

// Παράδειγμα τύπου αναφοράς - αποθηκεύεται στον σωρό
class Circle {
    var radius: Double

    init(radius: Double) {
        self.radius = radius
    }
}

var c1 = Circle(radius: 5.0)
var c2 = c1 // Μόνο η αναφορά αντιγράφεται

c2.radius = 10.0 // και το c1 αλλάζει, καθώς και οι δύο δείχνουν στο ίδιο αντικείμενο στον σωρό
print("c1.radius: \(c1.radius), c2.radius: \(c2.radius)") // Έξοδος: c1.radius: 10.0, c2.radius: 10.0