2012-09-11 10 views
5

Sto avendo un po 'di problemi nel capire se fare riferimento a se stessi all'interno di un blocco e non creare un ciclo di conservazione.blocchi, self, conserva cicli

Potete farmi sapere se la mia comprensione è corretta:

Se mai autoreferenzialità all'interno di un blocco, si creerà un ciclo di mantenere, e invece dovrei essere la creazione di una debole riferimento a sé al di fuori del blocco e quindi usando quel riferimento debole all'interno del blocco?

Grazie!

risposta

11

Sì, è corretto, con alcune eccezioni:

Un mantenere ciclo avviene solo se self finisce mantenendo il blocco indirettamente, ad esempio impostando la proprietà myblock sulla proprietà di selfmyproperty:

self.myproperty.myblock = ^{ [self dosomething]; }; // ERROR: Retain Cycle 

Tuttavia, un ciclo di conservare non (di solito) avviene quando si utilizza blocchi per qualcosa come il codice di spedizione, in questo modo:

dispatch_async(dispatch_get_main_queue(), ^{ [self dosomething]; }); // Safe, dispatch_async will not be retained by you 

A meno che, naturalmente, chiami la funzione dispatch_async all'interno di un blocco che ha i criteri per essere un ciclo di conservazione.

È davvero confuso, ed è qualcosa che spero venga risolto. Ora, per la mia opinione:


Non è stato sempre il caso, in pre ARC codice di questo non era un problema, ma dal momento che i blocchi ora mantengono automaticamente tutti gli oggetti che catturano, si tratta di un problema.

Vorrei che questo fosse risolto, in quanto sarebbe una soluzione abbastanza semplice, avendo il tipo self essere un __weak instancetype const invece di uno instancetype const. Risolverà anche alcuni problemi con la creazione di cluster di classi in ARC, che certamente non è il più grande dei problemi, ma esiste ancora.

Per quanto riguarda i vantaggi dei cicli di mantenimento, non ce ne sono molti.

+1

Un ciclo di mantenimento non è strettamente un errore - è spesso possibile che il proprietario del Blocco disponga di quel Blocco prima della sua stessa distruzione, interrompendo il ciclo ed evitando qualsiasi problema. –

+0

È sicuro creare semplicemente un riferimento debole a sé e usare sempre quel riferimento debole all'interno del blocco, solo per garantire un ciclo di conservazione? (Supponendo che sia ok con la possibilità che quando il blocco viene eseguito, selfWeak può essere un puntatore nullo?) –

+0

@WiseShepherd ovviamente, è così che si riparano i cicli di conservazione, nella maggior parte delle situazioni. –