33

nehme ich schon ein schwaches SelbstMit Bezug auf schwache selbst in einem verschachtelten Block

__weak typeof(self) weakSelf = self; 
[self doABlockOperation:^{ 
     ... 
    }]; 

Innerhalb dieses Blocks, wenn ich Nest ein weiterer Block mit erstellen:

[weakSelf doAnotherBlockOperation:^{ 
      [weakSelf doSomething]; 
} 

wird es einen Zyklus beibehalten schaffen? Muss ich eine weitere schwache Referenz zum weakself erstellen?

__weak typeof(self) weakerSelf = weakSelf; 
[weakSelf doAnotherBlockOperation:^{ 
       [weakerSelf doSomething]; 
    } 

Antwort

19

Kommt drauf an.

Sie erstellen nur einen Retain-Zyklus, wenn Sie den Block tatsächlich speichern (weil self auf den Block zeigt und Punkte auf self blockiert). Wenn Sie nicht beabsichtigen, einen der Blöcke zu speichern, ist die Verwendung des starken Verweises auf self gut genug --- Block wird zuerst freigegeben, nachdem er ausgeführt wurde, und dann wird der Zeiger auf self freigegeben.

In Ihrem speziellen Beispiel müssen Sie keine schwächerenWeakerEvenWeakerSelfs erstellen, es sei denn, Sie führen mehr Operationen durch, die nicht angezeigt werden.

+0

Also ich verstehe den Teil über ein schwaches Selbst wird benötigt, wenn zum Beispiel Selbst den Block behält. Aber welche Art von Operationen könnte ich durchführen, dass ich schwächere selbst brauche? –

+0

Eigentlich denke ich, dass du nie 'schwächereSelbst' brauchen wirst - schwache Zeiger sind so markiert, dass sie die Referenzzahl nicht erhöhen, und daher gibt es keine Möglichkeit, sie" schwächer "zu machen. –

55

Ihr Code funktioniert einwandfrei: Die schwache Referenz verursacht keinen Retain-Zyklus, da Sie ARC explizit anweisen, die RetainCount-Zahl Ihres schwachen Objekts nicht zu erhöhen. Für die beste Vorgehensweise sollten Sie jedoch eine starke Referenz Ihres Objekts erstellen, indem Sie die schwache verwenden. Dies erzeugt keinen Rückhaltezyklus, da der starke Zeiger innerhalb des Blocks nur existiert, bis der Block vollendet ist (es ist nur der Gültigkeitsbereich der Block selbst).

__weak typeof(self) weakSelf = self; 
[self doABlockOperation:^{ 
    __strong typeof(weakSelf) strongSelf = weakSelf; 
    if (strongSelf) { 
     ... 
    } 
}]; 
+1

Kannst du ein wenig mehr erzählen oder mir ein paar Links geben, warum ich einen starken Bezug zu meinem Objekt herstellen soll, indem ich den schwachen benutze? 1 oder 2 praktische Fälle würden viel helfen. Vielen Dank. –

+2

Das Gute daran ist, dass Sie sicher überprüfen können, ob das Objekt noch existiert, wenn der Block ausgeführt wird. Sonst wirst du nil aufrufen, was bedeutet, dass dein Block nicht viel tun wird. Ich rate euch, schaut [dieses Video von der WWDC 2012] (https://developer.apple.com/videos/wwdc/2012/?id=712);). –

+1

10 @EnzoTran: Sie möchten eine starke Referenz erstellen, da die schwache Referenz "sicher" ist, nur weil Sie wissen, dass "selbst" immer noch ein gültiges Objekt ist, wenn der Block ausgeführt wird. Aber es gibt keine Garantie, dass es nicht freigegeben wird, wenn der innere Block ausgeführt wird, weshalb es eine starke Referenz erfassen sollte. – newacct