> For the complete documentation index, see [llms.txt](https://swift.unicorndonkeys.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://swift.unicorndonkeys.com/guida-al-linguaggio/deinizializzazione.md).

# Deinizializzazione (Deinitialization)

Rilascia le risorse che richiedono una pulizia personalizzata.

Un *deinizializzatore* viene chiamato immediatamente prima che un'istanza di una classe venga deallocata. Scrivi i deinizializzatori con la parola chiave `deinit`, in modo simile a come gli inizializzatori si scrivono con la parola chiave `init`. I deinizializzatori sono disponibili solo per i tipi classe.

## Come funziona la deinizializzazione <a href="#come-funziona-la-deinizializzazione" id="come-funziona-la-deinizializzazione"></a>

Swift dealloca automaticamente le tue istanze quando non sono più necessarie, per liberare risorse. Swift gestisce la memoria delle istanze tramite il *conteggio automatico dei riferimenti* (*ARC*, Automatic Reference Counting), come descritto in [Conteggio automatico dei riferimenti](/guida-al-linguaggio/conteggio-automatico-dei-riferimenti.md). Di solito non hai bisogno di eseguire una pulizia manuale quando le tue istanze vengono deallocate. Tuttavia, quando lavori con risorse tue, potresti aver bisogno di eseguire personalmente qualche pulizia aggiuntiva. Per esempio, se crei una classe personalizzata per aprire un file e scriverci dei dati, potresti aver bisogno di chiudere il file prima che l'istanza della classe venga deallocata.

Le definizioni di classe possono avere al massimo un deinizializzatore per classe. Il deinizializzatore non accetta alcun parametro e si scrive senza parentesi:

```swift
deinit {
    // esegui la deinizializzazione
}
```

I deinizializzatori vengono chiamati automaticamente, subito prima che avvenga la deallocazione dell'istanza. Non ti è permesso chiamare personalmente un deinizializzatore. I deinizializzatori della superclasse vengono ereditati dalle loro sottoclassi, e il deinizializzatore della superclasse viene chiamato automaticamente al termine dell'implementazione del deinizializzatore di una sottoclasse. I deinizializzatori della superclasse vengono sempre chiamati, anche se una sottoclasse non fornisce un proprio deinizializzatore.

Poiché un'istanza non viene deallocata finché non è stato chiamato il suo deinizializzatore, un deinizializzatore può accedere a tutte le proprietà dell'istanza su cui viene chiamato e può modificare il proprio comportamento in base a tali proprietà (per esempio cercando il nome di un file che deve essere chiuso).

## I deinizializzatori in azione <a href="#i-deinizializzatori-in-azione" id="i-deinizializzatori-in-azione"></a>

Ecco un esempio di deinizializzatore in azione. Questo esempio definisce due nuovi tipi, `Bank` e `Player`, per un semplice gioco. La classe `Bank` gestisce una valuta inventata, che non può mai avere più di 10.000 monete in circolazione. Nel gioco può esserci sempre e solo una `Bank`, e quindi `Bank` è implementata come una classe con proprietà e metodi di tipo per memorizzare e gestire il suo stato corrente:

```swift
class Bank {
    static var coinsInBank = 10_000
    static func distribute(coins numberOfCoinsRequested: Int) -> Int {
        let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank)
        coinsInBank -= numberOfCoinsToVend
        return numberOfCoinsToVend
    }
    static func receive(coins: Int) {
        coinsInBank += coins
    }
}
```

`Bank` tiene traccia del numero corrente di monete che possiede con la sua proprietà `coinsInBank`. Offre inoltre due metodi — `distribute(coins:)` e `receive(coins:)` — per gestire la distribuzione e la raccolta delle monete.

Il metodo `distribute(coins:)` verifica che ci siano abbastanza monete nella banca prima di distribuirle. Se le monete non sono sufficienti, `Bank` restituisce un numero inferiore a quello richiesto (e restituisce zero se nella banca non è rimasta alcuna moneta). Restituisce un valore intero per indicare il numero effettivo di monete fornite.

Il metodo `receive(coins:)` si limita ad aggiungere il numero di monete ricevute alla riserva di monete della banca.

La classe `Player` descrive un giocatore nel gioco. Ogni giocatore ha in ogni momento un certo numero di monete conservate nel suo borsellino. Questo è rappresentato dalla proprietà `coinsInPurse` del giocatore:

```swift
class Player {
    var coinsInPurse: Int
    init(coins: Int) {
        coinsInPurse = Bank.distribute(coins: coins)
    }
    func win(coins: Int) {
        coinsInPurse += Bank.distribute(coins: coins)
    }
    deinit {
        Bank.receive(coins: coinsInPurse)
    }
}
```

Ogni istanza di `Player` viene inizializzata con una dotazione iniziale di un numero specificato di monete prelevate dalla banca durante l'inizializzazione, anche se un'istanza di `Player` può ricevere meno monete di quel numero se non ce ne sono abbastanza disponibili.

La classe `Player` definisce un metodo `win(coins:)`, che preleva un certo numero di monete dalla banca e le aggiunge al borsellino del giocatore. La classe `Player` implementa anche un deinizializzatore, che viene chiamato subito prima che un'istanza di `Player` venga deallocata. Qui, il deinizializzatore si limita a restituire alla banca tutte le monete del giocatore:

```swift
var playerOne: Player? = Player(coins: 100)
print("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
// Stampa "A new player has joined the game with 100 coins".
print("There are now \(Bank.coinsInBank) coins left in the bank")
// Stampa "There are now 9900 coins left in the bank".
```

Viene creata una nuova istanza di `Player`, con una richiesta di 100 monete, se disponibili. Questa istanza di `Player` viene memorizzata in una variabile `Player` opzionale chiamata `playerOne`. Qui si usa una variabile opzionale, perché i giocatori possono lasciare il gioco in qualsiasi momento. L'opzionale ti permette di tenere traccia della presenza o meno di un giocatore nel gioco.

Poiché `playerOne` è un opzionale, viene qualificato con un punto esclamativo (`!`) quando si accede alla sua proprietà `coinsInPurse` per stamparne il numero predefinito di monete, e ogni volta che viene chiamato il suo metodo `win(coins:)`:

```swift
playerOne!.win(coins: 2_000)
print("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
// Stampa "PlayerOne won 2000 coins & now has 2100 coins".
print("The bank now only has \(Bank.coinsInBank) coins left")
// Stampa "The bank now only has 7900 coins left".
```

Qui, il giocatore ha vinto 2.000 monete. Il borsellino del giocatore ora contiene 2.100 monete, e alla banca restano solo 7.900 monete.

```swift
playerOne = nil
print("PlayerOne has left the game")
// Stampa "PlayerOne has left the game".
print("The bank now has \(Bank.coinsInBank) coins")
// Stampa "The bank now has 10000 coins".
```

Ora il giocatore ha lasciato il gioco. Ciò viene indicato impostando la variabile opzionale `playerOne` a `nil`, che significa “nessuna istanza di `Player`”. Nel momento in cui questo accade, il riferimento della variabile `playerOne` all'istanza di `Player` viene interrotto. Nessun'altra proprietà o variabile fa ancora riferimento all'istanza di `Player`, e quindi questa viene deallocata per liberarne la memoria. Subito prima che ciò accada, il suo deinizializzatore viene chiamato automaticamente, e le sue monete vengono restituite alla banca.
