2011-10-18 16 views
7

stavo leggendo la documentazione ARC sul sito LLVM: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#autoreleasepoolsemantica @autoreleasepool

..nel particolare circa @autoreleasepool.

Nella maggior parte dell'attuale implementazione utilizzando NSAutoreleasePool, vedo casi in cui il pool viene periodicamente scaricato durante un'iterazione del ciclo - come facciamo lo stesso con il pool @autorelease, oppure è tutto fatto per noi in qualche modo sotto il cofano?

In secondo luogo, i documenti dichiarano che se viene lanciata un'eccezione, il pool non viene svuotato .... ok eccezioni sono per nome eccezionali, ma se succedono, si potrebbe voler recuperare senza perdere un carico di memoria . I documenti non specificano quando verranno rilasciati questi oggetti.

Qualcuno ha qualche informazione su questi punti?

risposta

9

In molti implementazione corrente utilizzando NSAutoreleasePool, vedo casi in cui la vasca viene svuotata periodicamente durante un ciclo di iterazione - come lo facciamo lo stesso con piscina @autorelease, o è tutto fatto per noi in qualche modo sotto il cofano ?

Allo stesso modo, vale a dire in cascata di pool di autorelease. Per esempio:

@autoreleasepool { 
    … 
    for (int i = 0; i < MAX; i++) { 
     @autoreleasepool { 
      … 
     } 
    } 
    … 
} 

In secondo luogo, i documenti affermano che, se viene generata un'eccezione, la piscina non viene drenata .... ok eccezioni sono per nome eccezionali, ma se accadono, come si potrebbe per recuperare senza perdere un carico di memoria. I documenti non specificano quando verranno rilasciati questi oggetti.

Nella maggior parte dei casi il programma non sarà in grado di recuperare con grazia a causa della natura peculiare delle eccezioni in Cocoa, quindi direi che perde oggetti è un problema minore. Se un blocco @autoreleasepool viene chiuso a causa di un'eccezione, gli oggetti autoreleased corrispondenti verranno rilasciati solo quando viene scoppiato uno dei pool di autorelease che li contengono. Ma è possibile, naturalmente, inserire blocchi @try/@catch/@finally all'interno del blocco @autoreleasepool per evitare che ciò accada.

+0

Penso che la seconda parte della risposta non sia giusta. i pool autorelease sono di fatto autoelocati nel pool autorelease in vigore al momento della loro allocazione. Finché l'eccezione non si propagherà oltre il pool di autorelease più esterno, nessun oggetto autoreleased perde. – JeremyP

+0

@Jer Hai ragione; Grazie per l'avviso! –

+0

@Bavarious - Grazie per l'ottima risposta. Di sicuro, perde la memoria in loop mentre si usa 'stringWithFormat'. –

2

come lo facciamo lo stesso con piscina @autorelease

Ti piace questa:

for (int i = 0; i < 10000; i++) { 
    @autoreleasepool { 
     // Do your work here 
     ... 
    } 
} 

In secondo luogo, i documenti affermano che, se viene generata un'eccezione, la piscina isn' t svuotato .... ok le eccezioni sono per nome eccezionali, ma se succedono, si potrebbe desiderare di recuperare senza perdere un carico di memoria.

AFAIK questo non è possibile con ARC. ARC non è assolutamente sicuro. Se si verifica un'eccezione, esiste la possibilità di perdite di memoria non recuperabili. Il codice che utilizza ARC non deve basarsi su eccezioni per la segnalazione degli errori. L'aspettativa è che il processo si arresti in ogni caso quando viene sollevata un'eccezione.