2013-03-19 4 views
5

Ich habe eine Methode, die einen Block und eine andere Methode gibt, die das Verfahren verwendet:iOS: Methode gibt einen Block zurück, dann wird der Block in Array gespeichert, wann sollte ich es kopieren?

- (MyBlock)blockForParameter:(id)param 
{ 
    MyBlock theBlock = ^(){NSLog(@"Param: %@", param);}; 
    return theBlock; 
} 

- (void)methodUser 
{ 
    MyBlock theBlock = [self blockForParameter:something]; 
    [self.allBlocks addObject:theBlock]; 
} 

Die Frage ist, wann soll ich den Block kopieren? Sollte ich den Block kopieren, wenn ich ihn in blockForParameter zurückgebe, oder sollte ich ihn kopieren, wenn ich ihn zum Array hinzufüge?

Dank

+0

müssen Sie es sogar in diesem Fall kopieren? Ein neuer 'MyBlock' wird jedes Mal erstellt, wenn Sie diese Funktion aufrufen, oder? Ich bin kein Experte mit Blöcken, aber das ist, was ich denke passieren würde. – Fonix

Antwort

3

Blöcke müssen kopiert werden, wenn sie „den Umfang überleben, in dem sie erstellt wurden“, so dass Sie den Block in Ihrem blockForParameter Methode kopiert werden müssen, bevor es zurückkehrt.

Bearbeiten: Mit ARC ist dies nicht mehr wahr. Siehe zum Beispiel Objective-C: blocks in ARC und die darin:

  • einen Block aus einer Funktion zurückkehrend erfordert nicht den Block zu kopieren.
  • Hinzufügen eines Blocks zu einer Sammlung erfordert eine Blockkopie.
+0

afaik, wenn ein Objekt, das in einem Bereich, der zu einer anderen Funktion zurückgegeben wurde, zurückgegeben wird, wird dieses Objekt am Leben erhalten, auch wenn der ursprüngliche Bereich abgeschlossen ist. .. oder sind einige Sonderfälle blockiert? – Fonix

+0

@Fonix: Blöcke sind etwas Besonderes, da sie auf dem Stack erstellt werden und auf den Heap verschoben werden müssen, wenn sie den Umfang ihrer Erstellung überstehen. –

+0

Im Falle von ARC, ist es nicht das gleiche, wenn ich es bei der Rückkehr kopieren und nicht kopieren, wenn Sie zu einer Sammlung hinzufügen? – hzxu

1

Schauen Sie sich jede Methode getrennt an.

In -blockForParameter: wird das Blockliteral von der Methode zurückgegeben. Der Block muss kopiert werden, um den Gültigkeitsbereich des Literals zu überleben. In MRC müssten Sie den kopierten und automatisch freigegebenen Block zurückgeben. In ARC müssen Sie nichts tun.

In -methodUser ist der Block in dieser Methode nicht definiert; Es wird von einem Methodenaufruf empfangen. Daher muss es bereits kopiert worden sein (d. H. Es ist kein Stapelblock). Daher müssen Sie nichts damit tun, wenn Sie dazu tun.

Verwandte Themen