Con l'uscita di Swift 5.5, il linguaggio ha integrato il concetto di ownership model e move semantics, che rafforzano il controllo sulla proprietà dei dati e consentono al compilatore di ottimizzare i movimenti, riducendo il numero di copie, il che è rilevante per scenari ad alte prestazioni.
La move semantics implica che durante la trasmissione di un valore (ad esempio, struct) è possibile "trasmettere" la proprietà di quel valore senza copiarlo. In questo caso, il compilatore può invalidare la variabile originale (simile a move in C++). Ora il modello di ownership e la move semantics sono più realizzati come esperimento (isolamento degli attori, tipi sendable, @_move, consuming/self-consuming) e promettono di apparire nell'API pubblica.
La principale differenza rispetto all'ARC è che la move semantics si applica ai value types, mentre l'ARC gestisce la vita degli oggetti di riferimento.
Esempio (semantica di proprietà, Swift 5.5+):
func consume<T>(_ x: __owned T) { /* ... */ } struct LargeArray { var storage: [Int] mutating func clear() { storage.removeAll() } consuming func consumeSelf() { // self non è accessibile dopo la chiamata } }
La gestione della proprietà consente di evitare copie indesiderate quando si lavora con grandi strutture.
Nuances:
Qual è la differenza tra la trasmissione di un oggetto struct a una funzione per valore, per riferimento e per move semantics in Swift?
Risposta:
Esempio:
func foo(_ x: MyStruct) { /* copia */ } func bar(_ x: inout MyStruct) { /* per riferimento */ } func baz(_ x: __owned MyStruct) { /* move semantics, non copia */ }
Storia
Nel progetto, durante la trasmissione di grandi strutture attraverso funzioni, si verificava sempre una copia implicita, aumentando i costi di memoria. Dopo l'implementazione della move semantics sperimentale e una gestione più ponderata della proprietà, è stato possibile ripartire il carico in modo pulito e accelerare le parti critiche.
Storia
Molti sviluppatori hanno utilizzato erroneamente inout, scambiando la sua funzionalità con move, mentre il valore rimane accessibile, portando a una proprietà ambigua della variabile, causando bug e violazioni della logica.
Storia
Errore nella gestione dei dati tra i thread: mancanza del qualificatore Sendable sulle strutture, che portava a copie inaspettate o errori di proprietà durante il lavoro asincrono con grandi strutture attraverso actor o Task.