Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 12 di 32
  • livello intermedio
Indice lezioni

Gestione della memoria e ARC

Come gestire in maniera corretta la memoria in un'applicazione iOS: la proprietà retainCount
Come gestire in maniera corretta la memoria in un'applicazione iOS: la proprietà retainCount
Link copiato negli appunti

In precedenza abbiamo trascurato l'invocazione del metodo release sugli oggetti, necessaria per una corretta gestione della memoria i cui concetti principali verranno introdotti di seguito. I dispositivi iOS non posseggono un Garbage Colllector il quale gestirebbe automaticamente la memoria dell'intero dispositivo, ma bensì delega agli sviluppatori una gestione della memoria "manuale" nello sviluppo delle loro applicazioni.

Fulcro della gestione della memoria è una proprietà che ogni oggetto possiede: il retainCount. Quest'ultimo indica il numero di riferimenti associati all'oggetto e quando il retainCount di qualsiasi oggetto arriva a 0 quest'ultimo viene deallocato.

Questa operazione viene effettuata da un oggetto chiamato AutoreleasePool che è istanziato non appena l'applicazione viene eseguita e si occupa di monitorare i retainCount degli oggetti all'interno dell'applicazione per deallocare quelli con valore 0.

Ma in che modo cambia il valore del retainCount? Quando un qualsiasi oggetto viene allocato ed inizializzato con i classici metodi alloc e init, il suo retainCount ha valore 1. Per modificare in maniera esplicita il retainCount di un oggetto allocato si possono usare due metodi:

  • retain: incrementa il retainCount di 1.
  • release: decrementa il retainCount di 1

Ritornando alla nostra "applicazione" di prova Hello World, e facendo un rapido conto del retainCount della label, abbiamo la sua inizializzazione (retainCount = 1) e poco dopo una chiamata al metodo release il quale, decrementando di uno il retainCount, verrebbe riportato a 0 e la label verrebbe deallocata.

Ma perché l'applicazione funziona correttamente anche se la label ha retainCount zero? Semplicemente perchè il retainCount non è 0; infatti, ricordando la definizione del retainCount (ossia che rappresenta il numero di riferimenti all'oggetto), l'invocazione del metodo addSubview sulla view del View Controller incrementa di 1 il retainCount della label (quindi dopo la chiamata a quel metodo il retainCount vale 2) in quanto aggiunge quest'ultima alla propria gerarchia ed ha bisogno di un riferimento esplicito alla label stessa. Infine con la chiamata al metodo release riportiamo il retainCount ad 1.

Ma quando verrà deallocata la label? Ciò avverrà quando il firstViewController verrà deallocato e dunque, non essendo più necessario il riferimento alla label, il suo retainCount verrà decrementato di 1 (assumendo dunque valore 0) e, finalmente, anche la label verrà deallocata.

Come abbiamo detto prima, dopo l'invocazione del metodo addSubView il retainCount della label viene portato a 2; risulta dunque indispensabile la chiamata esplicita al metodo release per riportare il retainCount dela label a 1 per poter essere deallocata nello scenario descritto poco sopra.

Errata gestione della memoria: leak e crash

Una errata gestione della memoria può portare ad uno dei seguenti problemi: un leak di memoria o un crash dell'applicazione.

Il primo problema è legato ad un retainCount di un oggetto troppo elevato. Tale oggetto non verrà mai deallocato (in quanto possiede un retainCount maggiore di 1) causando quindi uno "spreco" di memoria.

Il secondo problema (il crash dell'applicazione), è causato principalmente da un retainCount troppo basso su un oggetto che causa una deallocazione prematura dell'oggetto stesso. Di per se, la deallocazione prematura di un oggetto non causa il crash dell'applicazione, ma se per esempio proviamo ad invocare un metodo su tale oggetto l'applicazione crasherà dato che si sta provando ad accedere ad un'area di memoria vuota.

Analizzando i due scenari il primo è sicuramente meno critico, ma bisogna fare attenzione: se il numero di leak è elevato si rischia che l'applicazione uccupi una quantità di memoria eccessiva e, superata una certa soglia, il sistema operativo del dispositivo terminerà esso stesso l'applicazione.

ARC (Automatic Reference Counting)

Con il rilascio di Xcode 4.2 è stato introddo ARC, una funzionalità molto interessante che semplifica la vita agli sviluppatori. Utilizzando ARC lo sviluppatore non è più costretto ad invocare esplicitamente i metodi retain e release per mantenere un valore coerente del retainCount dell'oggetto, dato che queste direttive vengono inserite, a compile-time da ARC stesso. ARC dunque non è un garbage collector in quanto non lavora a run-time.

Nel tutorial pratico che presenteremo in questa guida utilizzeremo proprio ARC e dunque il lettore non troverà più riferimenti espliciti a metodi di retain e release.

Ti consigliamo anche