2011-10-25 20 views
42

Quali sono i vantaggi e gli svantaggi dell'utilizzo del nuovo stile di gestione della memoria ARC (Automatic Reference Counting) in un progetto iOS?Quali sono i vantaggi e gli svantaggi dell'utilizzo di ARC?

È possibile scegliere di non utilizzare ARC durante lo sviluppo con l'SDK di iOS 5.0?

Si consiglia l'ARC o il conteggio del riferimento manuale (MRC) per un nuovo progetto?

Un'applicazione che utilizza ARC può essere eseguita su versioni del sistema operativo precedenti rispetto a iOS 5.0?

+2

Sono disponibili diverse domande qui, due dei quali vengono affrontati nelle domande [Come funziona il nuovo meccanismo di conteggio automatica del riferimento?] (Http://stackoverflow.com/questions/6385212/how-does-the-new- automatico-di conteggio dei riferimenti meccanismo-lavoro) e [Xcode 4.2 con ARC: sarà il mio codice eseguito anche sui dispositivi iOS con firmware precedente alla 5.0?] (http://stackoverflow.com/questions/7768861/xcode-4-2 -con-arc-will-my-codice-run-anche-on-IO-dispositivi-con-firmware-vecchio-tha) –

risposta

60

Quali sono i vantaggi e gli svantaggi dell'utilizzo del nuovo stile di gestione della memoria di conteggio dei riferimenti automatici (ARC) in un progetto iOS?

L'esecuzione di un programma ARC è quasi identica alla MRC ben scritta. Cioè, le differenze comportamentali sono spesso inosservabili perché entrambi gli ordini e le prestazioni sono molto vicini.

Se sai già come implementare le app OS X o iOS con il conteggio dei riferimenti manuali (MRC), ARC non aggiunge realmente funzionalità, ma ti consente solo di rimuovere le operazioni di conteggio dei riferimenti dalle tue fonti.

Se non si desidera imparare MRC, si consiglia di provare prima ARC. Un sacco di persone lottano o tentano di ignorare le pratiche comuni di MRC (esempio: ho introdotto un numero di strumenti objc per l'analizzatore statico). Se vuoi evitare questi problemi, ARC ti permetterà di posticipare la tua comprensione; non è possibile scrivere programmi objc non banali senza comprendere il conteggio dei riferimenti e le durate e le relazioni tra oggetti, quali MRC, ARC o GC. ARC e GC rimuovono semplicemente l'implementazione dalle tue fonti e fanno la cosa giusta nella maggior parte dei casi. Con ARC e GC, dovrai comunque dare una guida.

Non ho rilevato questo, ma potrebbe essere opportuno ricordare che lo che compila le origini ARC richiederebbe più tempo e risorse.

Se il programma che si sta sviluppando è l'utilizzo piuttosto libera del conteggio dei riferimenti (per esempio una quantità tipica di autoreleases), il passaggio ad arco potrebbe davvero migliorare i tempi di esecuzione del programma e l'utilizzo della memoria di picco.

È possibile scegliere di non utilizzare ARC durante lo sviluppo con l'SDK di iOS 5.0?

Sì, utilizzando CLANG_ENABLE_OBJC_ARC. ARC è compatibile con i binari e tutto ciò che accade realmente è che il compilatore fa del proprio meglio per introdurre automaticamente le operazioni di conteggio di riferimento appropriate, in base alle dichiarazioni visibili alla traduzione corrente (see my answer here as to why translation visibility is important). Pertanto, è anche possibile abilitarlo e disabilitarlo per alcune fonti in un progetto e abilitarlo per gli altri.

La modalità mista (alcuni MRC e alcune sorgenti ARC) è tuttavia abbastanza complicata, e in modo sottile, in particolare le implementazioni di wrt che possono essere duplicate dal compilatore (ad esempio il corpo di una funzione inline potrebbe non essere corretto). Tali problemi in modalità mista saranno molto difficili da isolare. I programmi e le fonti di ObjC++ saranno in particolare difficili da questo punto di vista. Inoltre, il comportamento può variare in base alle impostazioni di ottimizzazione (come un esempio); un programma che funziona perfettamente in una build di debug può introdurre una perdita o uno zombie nel rilascio.

Si consiglia l'ARC o il conteggio del riferimento manuale (MRC) per un nuovo progetto?

Personalmente, rimarrò con MRC per qualche tempo. Anche se ARC è stato testato nell'uso del mondo reale, è probabile che ci siano ancora un numero di problemi che si presentano in scenari complessi, che vorrete evitare di essere i primi a conoscere e fare il debug. La Garbage Collection di OS X è un esempio del perché potresti voler aspettare. Ad esempio, lo switch potrebbe cambiare quando gli oggetti vengono distrutti: gli oggetti potrebbero essere distrutti prima e mai collocati nei pool di autorelease. Potrebbe anche cambiare l'ordine in cui vengono rilasciati gli ivar, che potrebbero avere alcuni effetti collaterali.

Ho anche una grande base di codice che non voglio perdere una settimana testando questa funzione per ora. Infine, la compatibilità all'indietro è ancora importante per me.

Un'applicazione che utilizza ARC può essere eseguita su versioni del sistema operativo precedenti rispetto a iOS 5.0?

Se sviluppi con MRC, sarà retrocompatibile. Se sviluppi con ARC, non sarà necessariamente compatibile. In effetti, potrebbe non essere nemmeno compilato senza un piccolo lavoro extra. I requisiti per il runtime sono disponibili in alcune versioni precedenti. See also this question. Se hai bisogno di compatibilità con le versioni precedenti, ARC non sarà un'opzione per alcune versioni del sistema operativo.

Infine, se si dovesse limitare la scelta a GC o ARC, raccomanderei ARC.

+5

Davvero un buon commento. Abbiamo discusso della migrazione del nostro grande progetto aziendale da MRC a ARC, ma pensiamo che sia meglio utilizzare MRC su grandi progetti o con modelli di oggetti complicati perché ne abbiamo il controllo. Nella maggior parte dei casi, non chiamiamo neanche mantenere/rilasciare manualmente. Abbiamo mantenuto le proprietà per tutto e ci autorelease al momento dell'assegnazione. Ma di tanto in tanto troviamo una situazione in cui abbiamo bisogno di un controllo diretto sulla memoria. – Sulthan

+0

Non ho passato una settimana ma due giorni a migrare la mia libreria 2D basata su OpenGL ES e posso dirti ... Se accedi direttamente a ivars tutto il tempo (per evitare un sovraccarico, e perché sai cosa stai facendo), tu avere un sacco di delegati sparsi per il quale hai dimenticato di aggiungere __unsafe_unretained, ecc ... Puoi finire con un sacco di cicli di conservazione, implementando -dealloc solo per aggiungere un NSLog per vedere se un oggetto è deallocato, un sacco di mal di testa nel mio caso . Aggiungete a questi problemi di compatibilità Xcode, bug nell'assistente, migrazioni fallite ... –

+0

Per il momento, io ** adotterò ARC ma solo per piccoli progetti basati su UIKit dove posso permettermi di usare self.this self .che tutto il tempo e tutto si adatta ai casi d'uso previsti di Apple. –

1

si accende e accende con CLANG_ENABLE_OBJC_ARC = NO vantaggio è necessario scrivere meno codice e la gestione della memoria è più facile. Lo svantaggio è che devi cancellare tutto ciò che hai imparato sulla gestione della memoria :) Preferisco disattivarlo.

+0

Non ci può essere anche una piccola riduzione delle prestazioni se si utilizza ARC –

+0

realtà ARC è di solito più veloce in fase di esecuzione , soprattutto perché l'ottimizzatore rilascia gli oggetti appena possibile e si affida ai pool di autorelease meno. – pchap10k

+2

È più complesso di così. ARC è più veloce * e * più lento, a seconda della situazione. I risultati tipici sono: più ritardi e rilasci (più lenti), meno autoreleases (più veloce, meno memoria). L'unico modo per sapere se è più veloce o più lento per il tuo particolare codice è misurare. –

0

È possibile attivare ARC tramite "Modifica-> Refactor-> Converti in arco di Objective C", questo ridicherà completamente il codice (eliminare tutte le chiamate di gestione della memoria e così via). Non c'è operazione inversa quindi assicurati di avere le cose sotto controllo del codice sorgente se hai dei ripensamenti. This post mostra come disattivarlo per file specifici. Non penso ci siano troppe discussioni da fare per non volerci sfuggire al fatto che fa male vedere tutti questi sforzi messi in buona gestione della memoria andare in malora e che dovremo smettere di saltare al soffitto ogni volta che vediamo init, new, copy senza una corrispondente release/autorelease (e ci vorrà un po 'di tempo per abituarcisi). Forse si potrebbe sostenere che in alcune circostanze la gestione della memoria manuale produce miglioramenti delle prestazioni/memoria dell'impronta davvero notevoli, se così fosse sarei anche interessato.

0

Sto utilizzando Lion e xcode 4.3. Ho avuto lo stesso problema.

Per risolvere il problema ho girato il "Build Impostazioni-> Objective-C automatico Co riferimento" a "No".

Per verificare che fosse impostato su "Sì", ho dovuto abilitare anche le opzioni "Tutto" e "Livelli" sulla barra degli strumenti appena sotto la barra degli strumenti "Impostazioni di creazione".

Una volta attivate queste opzioni, ho potuto vedere che il mio progetto aveva quell'opzione impostata su "Sì". Mi ci è voluto un po 'per capire che l'impostazione predefinita era "No", che è ciò che viene visualizzato fino a quando non ho attivato l'opzione "Livelli".

Problemi correlati