Un altro schema che ho visto utilizzato è abbastanza interessante in questo aspetto è Conteggio dei riferimenti automatici di Swift e Objective-C .
Se non hai familiarità con esso, il conteggio dei riferimenti è un metodo in cui ogni oggetto ha uno stato (quindi forse non è adatto per la programmazione funzionale - non sono proprio sicuro) che tiene traccia di quanti altri oggetti lo stanno usando . Con il conteggio dei riferimenti manuale, quando si assegna un nuovo oggetto, l'oggetto ha un conteggio di riferimento di 1. Se un altro oggetto desidera utilizzare quell'oggetto, chiamerà un metodo "retain" sull'oggetto e questo incrementerà il conteggio dei riferimenti. Quando hanno finito, chiamano "release" e il conteggio dei riferimenti scende. Quando il conteggio dei riferimenti raggiunge 0, l'oggetto si cancella da sé.
Questo è il conteggio dei riferimenti manuale. Con il conteggio dei riferimenti automatico, lo sviluppatore non mantiene mai esplicitamente o rilascia nulla. Il compilatore gestisce tutti i dettagli di ciò per te. Assegni semplicemente un oggetto e poi, come per magia, quando hai finito di usarlo, viene liberato. La magia è che il compilatore si accorge quando fai cose come compiti e chiamate di conservare e rilasciare per te. Ciò comporta alcune annotazioni aggiuntive nel codice in modo che il compilatore possa capire come verrà utilizzato un oggetto. Potresti quindi contrassegnare un valore che considererai "strong" e uno che usi ma che non possiedi come "debole", ad esempio. A causa di impostazioni predefinite per lo più sensibili, non è necessario annotare la maggior parte dei valori, poiché i valori predefiniti sono quelli desiderati.
È stato suggerito che questo è simile alla garbage collection. Non sono d'accordo. Ad esempio, l' articolo di Wikipedia su ARC dice:
ARC differs from tracing garbage collection in that there is no background process that deallocates the objects asynchronously at runtime.
Quando esegui il conteggio dei riferimenti manuali, spesso hai un pool di autorelease, quindi non vai più di 1 ciclo di eventi senza effettuare la pulizia, e in effetti puoi creare un pool di autorelease in qualsiasi momento con qualsiasi ambito desideri, quindi è controllato dallo sviluppatore. Non succede in un futuro futuro sconosciuto che potrebbe interrompere altri lavori. Inoltre, quando fatto automaticamente, non è affatto come la raccolta dei rifiuti. A quanto ho capito, la liberazione della memoria avverrà immediatamente quando, per esempio, assegni un puntatore da un vecchio oggetto a un nuovo oggetto. Questo è molto diverso da un garbage collector che effettua periodicamente una pulizia e molto più vicino alla gestione manuale delle risorse tramite cose come malloc
e free
. Nella mia esperienza le implicazioni di rendimento del conteggio dei riferimenti, in particolare il conteggio dei riferimenti automatici, sono migliori e più prevedibili della garbage collection. Ma ammetto che non ho fatto molto con la garbage collection.