Il problema principale legato alla memoria di cui dovrai ancora essere a conoscenza è il mantenimento dei cicli. Ciò si verifica quando un oggetto ha un puntatore forte su un altro, ma l'oggetto target ha un puntatore forte sull'originale. Anche quando tutti gli altri riferimenti a questi oggetti vengono rimossi, si aggrapperanno l'uno all'altro e non verranno rilasciati. Questo può accadere anche indirettamente, da una catena di oggetti che potrebbe avere l'ultimo nella catena che fa riferimento a un oggetto precedente.
È per questo motivo che esistono i qualificatori di proprietà __unsafe_unretained
e __weak
. Il primo non manterrà alcun oggetto a cui punta, ma lascia aperta la possibilità che quell'oggetto vada via e che punti a cattiva memoria, mentre il secondo non mantiene l'oggetto e si imposta automaticamente su zero quando il suo bersaglio viene deallocato. Dei due, __weak
è generalmente preferito su piattaforme che lo supportano.
Utilizzeresti questi qualificatori per cose come i delegati, in cui non vuoi che l'oggetto mantenga il suo delegato e potenzialmente porti a un ciclo.
Un'altra coppia di problemi significativi legati alla memoria sono la gestione degli oggetti Core Foundation e la memoria allocata usando malloc()
per tipi come char*
. ARC non gestisce questi tipi, solo oggetti Objective-C, quindi dovrai comunque gestirli da solo. I tipi di Core Foundation possono essere particolarmente complicati, perché a volte devono essere collegati tra loro per abbinare gli oggetti Objective-C e viceversa. Ciò significa che il controllo deve essere trasferito avanti e indietro da ARC quando si collega tra tipi CF e Objective-C. Sono state aggiunte alcune parole chiave correlate a questo ponte e Mike Ash ha una grande descrizione di vari casi di ponte nel suo lungo write-up ARC .
Oltre a questo, ci sono molti altri casi meno frequenti, ma ancora potenzialmente problematici, nei quali la specifica pubblicata viene approfondita.
Gran parte del nuovo comportamento, basato sul mantenere gli oggetti in giro fino a quando c'è un forte puntatore ad essi, è molto simile alla garbage collection sul Mac. Tuttavia, le basi tecniche sono molto diverse. Piuttosto che avere un processo di garbage collector che viene eseguito a intervalli regolari per ripulire gli oggetti a cui non viene più indicato, questo stile di gestione della memoria si basa sulle rigide regole di conservazione / rilascio a cui tutti dobbiamo obbedire in Objective-C.
ARC prende semplicemente le ripetitive attività di gestione della memoria che abbiamo dovuto svolgere per anni e le scarica nel compilatore, così non dovremo più preoccuparci di esse. In questo modo, non si hanno problemi di arresto o profili di memoria a dente di sega riscontrati su piattaforme di raccolta rifiuti. Ho sperimentato entrambi questi nelle mie applicazioni Mac raccolte di rifiuti e sono ansioso di vedere come si comportano sotto ARC.
Per ulteriori informazioni sulla garbage collection vs. ARC, vedi questa risposta molto interessante di Chris Lattner nella mailing list di Objective-C , dove elenca molti vantaggi di ARC rispetto a Garbage Collection 2.0. Ho incontrato alcuni dei problemi di GC che descrive.