considerare questo avvertimento:
Catturare self
fortemente in questo blocco rischia di portare ad una trattenere ciclo
Quando si riceve l'avviso di cui sopra, si dovrebbe rivedere il tuo blocco per:
- eventuali riferimenti espliciti a
self
; oppure
- qualsiasi riferimento implicito a
self
causato dal riferimento a qualsiasi variabile di istanza.
Immaginiamo che abbiamo un po 'semplice proprietà di classe che era un blocco (questa sperimenterà lo stesso "mantenere ciclo" avvisi come tua domanda, ma non mancherà di tenere i miei esempi un po' più semplice):
@property (nonatomic, copy) void (^block)(void);
E supponiamo che abbiamo avuto qualche altra proprietà di classe abbiamo deciso di utilizzare all'interno del nostro blocco:
@property (nonatomic, strong) NSString *someString;
Se si fa riferimento self
all'interno del blocco (nel mio esempio qui di seguito, nel processo di accesso questa proprietà), è ovviamente ricevere tale avviso circa il rischio trattenere ciclo:
self.block = ^{
NSLog(@"%@", self.someString);
};
Quella essere risolti tramite il modello che ha suggerito, e cioè:
__weak typeof(self) weakSelf = self;
self.block = ^{
NSLog(@"%@", weakSelf.someString);
};
Meno ovvio, riceverete anche la "trattenere ciclo di" avviso se si fa riferimento una variabile della classe esempio all'interno del blocco, ad esempio:
self.block = ^{
NSLog(@"%@", _someString);
};
Questo perché la variabile di istanza _someString
porta un riferimento implicito a self
, ed è in realtà equivale a:
self.block = ^{
NSLog(@"%@", self->_someString);
};
Si potrebbe essere propenso a cercare di adottare modello sé debole anche qui, ma non si può.Se si tenta il modello weakSelf->_someString
della sintassi, il compilatore vi avvertirà di questo:
Dereferenziare un puntatore __weak
non è consentito a causa di possibili valore nullo causato dalla condizione di competizione, assegnarlo alla strong
variabile prima
È quindi risolvere ciò utilizzando il modello weakSelf
, ma anche creare una variabile locale strong
all'interno del blocco e l'uso che di dereference la variabile di istanza:
__weak typeof(self) weakSelf = self;
self.block = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"%@", strongSelf->_someString);
// or better, just use the property
//
// NSLog(@"%@", strongSelf.someString);
}
};
Come parte, questa creazione di un riferimento locale strong
, strongSelf
, all'interno del blocco presenta anche altri vantaggi, vale a dire che se il blocco di completamento è in esecuzione in modo asincrono su un thread diverso, non è necessario preoccuparsi di self
deallocato mentre il blocco è in esecuzione, con conseguenze non intenzionali.
Questo modello weakSelf
/strongSelf
è molto utile quando si tratta di proprietà di blocco e si desidera impedire mantenere cicli (alias cicli riferimento forti), ma al tempo stesso che self
non può essere deallocato nel mezzo dell'esecuzione del blocco di completamento.
FYI, Apple discute questo modello nella discussione "cicli non banali" più avanti nella sezione Use Lifetime Qualifiers to Avoid Strong Reference Cycles della Transizione alle note di rilascio ARC.
di segnalare che hai ricevuto qualche "errore" quando si fa riferimento weakSelf.generalInstaImage
nel tuo esempio. Questo è il modo corretto per risolvere questo avviso di "conservazione del ciclo", quindi se hai ricevuto un avvertimento, dovresti condividerlo con noi, oltre a mostrarci come hai dichiarato la proprietà.
qual è l'errore? prova ad usare 'id' o il nome effettivo della classe invece di' typeof (self) ' – Fonix