Domanda

Sto creando un'applicazione per iPhone in cui scollego alcuni thread per eseguire lavori di lunga durata in background in modo da non bloccare l'interfaccia utente. Comprendo che i thread richiedono istanze NSAutoreleasePool per la gestione della memoria. Quello di cui non sono sicuro è se il metodo threaded chiama un altro metodo - quel metodo ha bisogno anche di un NSAutoreleasePool?

Codice di esempio:

- (void)primaryMethod {
    [self performSelectorInBackground:@selector(threadedMethod) withObject:nil];
}

- (void)threadedMethod {
    NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];

    // Some code here

    [self anotherMethod];

    // Maybe more code here

    [aPool drain];
}

- (void)anotherMethod {
    // More code here
}

Il motivo per cui chiedo è che sto ricevendo errori che gli oggetti vengono rilasciati automaticamente senza pool in atto e che stanno perdendo. "

Ho visto altre domande in cui le persone non disponevano di pool di autorelease e capisco perché è necessario un pool di autorelease. Sono particolarmente interessato a scoprire se un pool di rilascio automatico creato in (in questo esempio) threadedMethod si applica agli oggetti creati in anotherMethod .

È stato utile?

Soluzione

Per rispondere alla tua domanda, sì, un altroMethod sta usando il NSAutoreleasePool che hai creato in threadedMethod, e tutto ciò che rilasci automaticamente verrà rilasciato quando unPool viene rilasciato / svuotato.

Quindi è improbabile che il tuo errore derivi direttamente da questo codice (a meno che non ci sia altro in corso).

Metti un punto di interruzione su _NSAutoreleaseNoPool (aggiungilo per nome nella finestra Breakpoints) ed esegui il tuo codice nel debugger e si fermerà quando viene chiamato il rilascio automatico senza un pool e questo dovrebbe risolvere il tuo problema.

Altri suggerimenti

Nel tuo esempio, sì, NSAutoreleasePool sta effettuando diversi metodi poiché l'invocazione di [self anotherMethod] è nidificata all'interno - (void) threadedMethod .

  • D: NSAutoreleasePool che trasporta metodi?
  • A: dipende:
    1. Attraverso invocazioni nidificate, sì.
    2. Attraverso invocazioni di fratelli, no.

E non importa quale sia, l'istanza NSAutoreleasePool stessa non rientra nell'ambito quando l'ambito padre scompare. - nel tuo esempio, alla fine di - (void) threadedMethod {} .

L'articolo menzionato in precedenza ( http://thegothicparty.com/dev/macos/nsautoreleasepool/ ) è abbastanza chiaro al riguardo.

Il pool di rilascio automatico passa a un altro metodo. Tuttavia, al termine della funzione thread, è necessario chiamare [aPool release] anziché [aPool drain]. Sono all'incirca equivalenti, ma la versione aPool provoca il rilascio di NSAutoreleasePool in aggiunta a tutti gli altri oggetti nel pool. Quando la funzione con thread termina dopo aver chiamato drain, il pool di rilascio automatico ha ancora un conteggio di mantenimento di +1! Le probabilità sono, il "quoting just leaking" object è aPool!

EDIT:

Jim Puls ha ragione sul rilascio e lo scarico equivalenti. I documenti di Apple affermano chiaramente che sono identici nell'ambiente non immondizia raccolto e che lo scolo è migliore nel caso di immondizia raccolta. Colpa mia per non aver letto i documenti!

Ecco un articolo che presenta una panoramica generale di NSAutoreleasePools: dovrebbe aiutarti a orientarti nella giusta direzione. Poiché esiste uno stack virtuale di pool di rilascio automatico, quello più in alto verrà utilizzato ovunque all'interno della tua app, indipendentemente da dove gli oggetti vengono rilasciati automaticamente.

http://thegothicparty.com/dev/macos/nsautoreleasepool/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top