W Swift istnieją dwa podstawowe typy danych: value types (typy wartości) i reference types (typy referencyjne).
struct), wyliczenia (enum) oraz typy podstawowe, takie jak Int, Double, Bool. Przy przekazywaniu lub przypisywaniu wartość jest kopiowana, co oznacza, że zmiany w kopii nie wpływają na oryginał.class) i pokrewne typy. Przy przekazywaniu nie kopiowany jest sam obiekt, lecz odniesienie do niego, więc zmiany poprzez jeden wskaźnik są widoczne także przez inne.Kiedy używać:
CGPoint, CGSize, modele, które nie powinny dzielić stanu).Przykład:
struct Point { var x: Int var y: Int } class Person { var name: String init(name: String) { self.name = name } } var p1 = Point(x: 0, y: 0) var p2 = p1 p2.x = 10 // p1.x pozostaje 0 var person1 = Person(name: "Alex") var person2 = person1 person2.name = "Sam" // person1.name również staje się "Sam"
Czym różni się let dla struct i class? Czy instancja class, stworzona za pomocą let, jest całkowicie niezmiennicza?
Odpowiedź:
Dla value types (struct) let czyni obiekt i jego właściwości niezmiennymi.
Dla reference types (class) let zakazuje ponownego przypisywania odniesienia, ale nie chroni właściwości obiektu. Można je zmieniać, jeśli nie są zadeklarowane jako let wewnątrz klasy.
Przykład:
class Box { var value: Int init(value: Int) { self.value = value } } let box = Box(value: 10) box.value = 20 // OK! // box = Box(value: 30) // Błąd: nie można ponownie przypisać box
Historia
W aplikacji płatniczej model transakcji był definiowany jako klasa, mimo że stanu być nie powinno. Powstał błąd: podczas jednoczesnej pracy z listą transakcji dochodziło do nieprzewidywalnej edycji danych różnych części interfejsu. Postanowiono przekształcić modele w struct, aby każdy komponent pracował z własną kopią.
Historia
W projekcie przechowywano ustawienia użytkownika w klasie, sądząc, że wartości są kopiowane przy przekazywaniu. Podczas zmiany danych jeden ekran przypadkowo wpływał na inny, ponieważ oba pracowały z tym samym odniesieniem do obiektu.
Historia
W module serializacji dane modelu były zadeklarowane jako reference type, co prowadziło do uszkodzenia stanu w pamięci podręcznej przy każdej zmianie. Po wymianie na value types problem zniknął: dane stały się niezależne przy każdej operacji.