24

Prima ARC ho avuto il seguente codice che conserva il delegato mentre un'operazione asincrona è in corso:manuale mantenere con ARC

- (void)startAsyncWork 
{ 
    [_delegate retain]; 
    // calls executeAsyncWork asynchronously 
} 

- (void)executeAsyncWork 
{ 
    // when finished, calls stopAsyncWork 
} 

- (void)stopAsyncWork 
{ 
    [_delegate release]; 
} 

Qual è l'equivalente a questo modello con ARC?

risposta

10

Perché non assegnare il proprio oggetto delegato a un ivar forte per la durata dell'attività asincrona?

o avere una variabile locale in executeAsyncWork

- (void)executeAsyncWork 
{ 
    id localCopy = _delegate; 

    if (localCopy != nil) // since this method is async, the delegate might have gone 
    { 
     // do work on local copy 
    } 
} 
+0

Grazie. Anche questa è stata la mia prima idea. Speravo che ci sarebbe stato un altro trucco carino ;-). – Alexander

+0

Esiste, usa GCD! ;-) – hypercrypt

+0

@hypercrypt: GCD non è una soluzione per fare in modo che la variabile si blocchi ma è un modo particolarmente carino per fare effettivamente il lavoro asincrono. – JeremyP

3

Qualcosa di simile a questo:

- (void)startAsyncWork 
{ 
    id<YourProtocol> delegate = _delegate; 
    dispatch_async(/* some queue */, ^{ 
     // do work 
     [delegate doSomething]; 
    } 
} 

Il blocco manterrà il delegato tutto il tempo necessario ...

31

ho bisogno di tanto in tanto per conservare e rilasciare manualmente le cose (a volte solo per il debug) e creato i seguenti macro:

Questo funziona utilizzando il __bridge_retained e __bridge_transfer per eseguire il cast delle cose da e verso (void *) che fa sì che le cose vengano mantenute, o per creare un riferimento forte senza chiamare retain.

Divertiti, ma attenzione!

+1

+1 per creare parole chiave di Google in parole in inglese –

+0

Molto bello - grazie! – Anthony

+0

Qual è il motivo per questa parte della prima macro: 'retainedThing = retainedThing'? – Anthony