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 self
myproperty
:
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.
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. –
È 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?) –
@WiseShepherd ovviamente, è così che si riparano i cicli di conservazione, nella maggior parte delle situazioni. –