Wie kann man das "Einfangen 'block' stark in diesem block wird wahrscheinlich führen zu eine retain-Zyklus"
Arbeite ich an diesem code, die nicht einige längere asynchrone Betrieb auf dem Netz und wenn es fertig ist löst es ein Abschluss-block, wo einige test ausgeführt wird und wenn eine variable eine bestimmte Wert eine weitere langwierige operation sollte sofort beginnen:
-(void) performOperation
{
void(^completionBlock) (id obj, NSError *err, NSURLRequest *request)= ^(id obj,NSError *err, NSURLRequest *request){
int variable=0;
//Do completion operation A
//...
//...
//Do completion operation B
//Get the variable value
if(variable>0){
[self doLengthyAsynchronousOperationWithCompletionBlock: completionBlock];
}
};
//Perform the lenhgty operation with the above completionBlock
[self doLengthyAsynchronousOperationWithCompletionBlock: completionBlock];
}
-(void) doLengthyAsynchronousOperationWithCompletionBlock: completionBlock
{
//Do some lengthy asynchronous stuff
}
Mit diesem code bekomme ich diese Warnung vom compiler:
WARNING: Block pointer variable 'completionBlock' is uninitialized when caputerd by the block
Ich geändert:
void(^completionBlock) (id obj, NSError *err, NSURLRequest *request)= ^(id obj,NSError *err, NSURLRequest *request)
in:
__block void(^completionBlock) (id obj, NSError *err, NSURLRequest *request)= ^(id obj,NSError *err, NSURLRequest *request)
aber ich bekomme diese Warnung:
WARNING 2: Capturing 'completionBlock' strongly in this block is likely to lead to a retain cycle
Wie kann ich dieses Problem beheben?
Dank
Nicola
- Haben Sie einen Blick auf dieses Antwort
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies geschieht, weil die block-Variablen initialisiert, um eine rekursive block müssen
__block
Speicher.__block
, in welchem Fall Sie übergeben als Referenz.__block
, wird der block erstellt werden mit Referenz auf die variable, statt. Dann ist die variable initialisiert wird, um den erstellten block und der block wird bereit sein, zu verwenden.Dies geschieht, weil eine block variable ist ein starker Verweis auf den block, und der block selbst verweisen auf die variable (denn wie wir gesehen haben, wird die variable hat einen
__block
so ist es referenziert statt kopiert).Also müssen wir
Den Namen
doLengthyAsynchronousOperationWithCompletionBlock
deutet darauf hin, dass die Methode möglicherweise überdauern den Gültigkeitsbereich der Methode, wo der block erstellt wird. Da der compiler nicht kopieren einen block als argument übergeben, es ist die Verantwortung dieser Methode zu kopieren, diese zu blockieren. Wenn wir über diesen block mit block-bewusst-code (zB:dispatch_async()
), geschieht dies automatisch.Hatten wir das schon zuordnen in diesem block eine Instanz-variable, wir brauchen eine
@property(copy)
und eine schwache Referenz auf sich selbst in den block, aber dies ist nicht der Fall, so dass wir Sie einfach selbst.__block
aufcompletionBlock
weil es nie benutzt in einem block! in der Tat, es ist niemals überall eingesetztself
ist nicht das, was die OP ' s Warnung über. Wir wissen nicht, obself
stark Referenzen der block (die OP zeigt uns nicht genug code, um zu sehen, dass), es ist also nicht sicher davon ausgehen, dass es sein muss__weak
completionBlock
nie verwendet und sollte entfernt werden. Und die__block
on weakCompletionBlock
ist nötig ist (also entfernen es falsch ist), da sein Wert nicht zugeordnet ist, durch die Zeit, die der block erstellt wird.completionBlock
wird später verwendet, um pass zudoLengthyAsynchronousOperationWithCompletionBlock: