2014-11-26 3 views
8

Sto pensando a pro e contro di Try-Catch in Objective-C. In base a questo articolo Miti Disperse NSException in iOS: possiamo utilizzarlo @ try ... @ catch, @finally?, try-catch non è poi così male, tranne che perde memoria in ARC.Perché "try catch" in Objective-C causa perdite di memoria?

Quindi, come fa try-catch a causare perdite di memoria?

+2

perché ObjC non è sicuro per le eccezioni di default (c'è un flag per renderlo sicuro delle eccezioni ma non ricorda i dettagli) –

+3

L'articolo, se dice che, è sbagliato. Ogni volta che qualcuno di Apple parla di questo, dicono molto chiaramente: "Non lanciare eccezioni come un modo di fare il controllo del flusso, le eccezioni sono per situazioni eccezionali e indesiderate e significa che vuoi andare in crash". Se pensi di aver bisogno di lanciare la tua eccezione, ripensaci. (Detto questo, vorrei che le persone dell'ufficio di sviluppo di AVFoundation prendessero il memo.) – matt

+0

Salvato la mia vita solo sapendo che lo fa! – mllm

risposta

13

Prima di tutto: le eccezioni hanno semantica diversa in Objective-C. Un'eccezione significa che qualcosa è andato completamente storto a causa di un errore di programmazione e l'ulteriore esecuzione dell'applicazione non è utile. Terminalo! Per gestire gli "errori attesi" (come input utente insufficiente o server non rispondenti e così via) utilizzare Cocoa's error handling pattern. (La ragione di ciò è che le eccezioni sembrano essere convenienti in molte situazioni, ma sono molto difficili da gestire in altre situazioni, ad esempio durante la costruzione di oggetti.) Leggi le eccezioni in C++. È doloroso.)

Per la tua Q: ARC aggiunge codice aggiuntivo per gestire la gestione della memoria. Questo codice deve essere eseguito per gestire la gestione della memoria, esp. rilasciare oggetti. Se si verifica un'eccezione prima che venga eseguita, il flusso di controllo non raggiunge mai l'istruzione di rilascio. Perdite di memoria.

- (void)method 
{ 
    id reference = …; 
    // Some ARC code to retain the object, reference points to. 
    … 
    @throw … 
    … 
    // reference loses its extent, because of method termination 
    // Some ARC code to release the object, reference points to. 
} 

Se si dispone di un'eccezione, il metodo è lasciato immediatamente e il codice ARC e la fine del metodo per rilasciare l'oggetto non viene mai eseguito. Questa è la perdita.

È possibile modificare questo comportamento compilando la sorgente con l'opzione -fobjc-arc-exceptions.

http://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions

Questo aggiungerà codice per rendere ARC sicura rispetto alle eccezioni che causa un calcio di rigore di esecuzione. Ma ci sono poche ragioni per farlo nello sviluppo del cacao, come spiegato all'inizio di questa risposta.