9

E 'un modello comune nel mio codice per allocare un oggetto, lasciare che faccia alcune cose con un gestore di completamento e rilasciarlo nel gestore:Come posso rilasciare un oggetto con un gestore di completamento blocchi sotto ARC?

LongOperation *foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [foo autorelease]; 
}]; 

Questo funziona abbastanza bene, ma quando tento di convertire il codice per ARC, Xcode giustamente si lamenta che non può semplicemente rilasciare il autorelease dal blocco, dal momento che renderebbe l'oggetto foo ottenere deallocato dopo aver lasciato l'ambito.

Quindi, qual è un buon modo per scrivere questo tipo di pattern sotto ARC? Potrei introdurre una variabile di istanza per foo:

[self setFoo:[[LongOperation alloc] init]]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [self setFoo:nil]; 
}]; 

... ma il codice non sarei rientrante più.

risposta

4

Nella maggior parte dei casi, dovrebbe funzionare (vale a dire, se qualcosa si riferisce all'interno di foo, foo durerà abbastanza a lungo da soddisfare quel codice prima di andare via). Se ci sono problemi con riferimenti deboli e in modo tale che foo sembra che dovrebbe andare via, ma non deve fino a dopo il gestore viene eseguito, si può fare qualcosa di simile:

__block LongOperation* foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // do some things 
    foo = nil; 
}]; 

Nota che questa è una specie di l'opposto di questo modello che fa sì che l'oggetto/non/venga catturato nelle regole della memoria gestita.

+0

Questo non risponde alla domanda è cosa fare quando il contesto che contiene foo è finito da tempo. Con questa soluzione, il frame dello stack che chiama [foo runWithCompletion:] deve bloccare fino a quando l'esecuzione non termina o rischia uno stack smasher. –

Problemi correlati