ich wie folgtdie Referenz auf einen starken innerhalb des Verschlusses, Speicherverwaltung konvertieren, schnell
class Sample {
deinit {
print("Destroying Sample")
}
func additionOf(a: Int, b:Int) {
print("Addition is \(a + b)")
}
func closure() {
dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
self?.additionOf(3, b: 3)
usleep(500)
self?.additionOf(3, b: 5)
}
}
}
Später irgendwann den behalten Zyklus in Schließung bin experimentieren, ich tue
var sample : Sample? = Sample()
sample?.closure()
dispatch_async(dispatch_get_global_queue(0, 0)) {
usleep(100)
sample = nil
}
wird der Ausgang
Addition is 6
Destroying Sample
sein Dies ist verständlich, weil self
nil out bevor Sie self?.additionOf(3, b:5)
Wenn ich eine Änderung innerhalb des Verschlusses gemacht durch eine andere Variable zu schaffen, die diesmal
dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.additionOf(3, b: 3)
usleep(500)
strongSelf.additionOf(3, b: 5)
}
wie folgt
zu
[weak self]
verweist, ist der Ausgang
Addition is 6
Addition is 8
Destroying C
Meine Frage ist, warum strongSelf
ist nicht Null nach sample = nil
. Ist es, weil es innerhalb des Verschlusses vor sample = nil
Wenn Sie 'sample = nil' setzen, wird nur der eine starke Verweis auf die' Sample' aufgelöst. Aber es hat keine Auswirkung auf andere starke Referenzen, die da draußen sein könnten (wie zum Beispiel "strongSelf", das zugewiesen wurde, bevor du "sample = nil" benutzt hast). Der ganze Zweck, ein "strongSelf" -Muster innerhalb der '[weak self]' -Schließung (manchmal scherzhaft "strongSelf/weakSelf-Tanz" genannt) zu machen, besteht darin, sicherzustellen, dass, wenn diese 'Probe' nicht freigegeben wurde, als diese Schließung begann, es wird es bis zum Abschluss dieser Schließung herum behalten. – Rob
@Rob: Ich glaube ich habe das aber nicht 100% verstanden. Vom OP aus, wenn die Schließung beginnt, wurde Sample noch nicht freigegeben, bis das erste 'additionOf (3, b: 3)' ausgeführt wird. Ich verstehe immer noch nicht, warum 'strongSelf' nicht verändert wird, weil das selbe nichts ist. – tonytran
Es ist nicht, dass es von der Schließung "gefangen" wird. Einfach, dass der Verschluss eine neue, zweite starke Referenz zum Objekt "Sample" etabliert hat. Also, wenn Sie 'var sample: Sample? = Sample() ', es gab eine starke Referenz. Wenn der Code auf "guard leave strongSelf = self else ..." trifft, ergibt sich eine zweite starke Referenz für insgesamt zwei starke Referenzen. Wenn Sie im Hauptthread "sample = nil" ausgeführt haben, ist immer noch eine starke Referenz vorhanden. Nur wenn "strongSelf" außerhalb des Gültigkeitsbereichs liegt, wird diese endgültige starke Referenz aufgelöst und das Objekt wird freigegeben. – Rob