Ich habe gerade ein sehr ekliges UIViewController
Leck, debuggen, so dass der UIViewController nicht freigegeben wurde auch nach dem Aufruf dismissViewControllerAnimated
.Warum gibt eine starke Referenz auf den übergeordneten UIViewController in performBatchUpdates eine Aktivität aus?
verfolgen ich das Problem mit dem folgenden Code-Block nach unten:
self.dataSource.doNotAllowUpdates = YES;
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
} completion:^(BOOL finished) {
self.dataSource.doNotAllowUpdates = NO;
}];
Grundsätzlich, wenn ich einen Anruf zu performBatchUpdates
mache und dann sofort dismissViewControllerAnimated
rufe, werden die UIViewController durchgesickert und die dealloc
Methode dieser UIViewController
nie wird angerufen. Der UIViewController bleibt für immer hängen.
Kann jemand dieses Verhalten erklären? Ich nehme an, performBatchUpdates
läuft über ein Zeitintervall, sagen wir, 500 ms, so würde ich davon ausgehen, dass nach diesem Intervall, würde diese Methoden aufrufen und dann die Dealloc auslösen.
Das Update scheint dies zu sein:
self.dataSource.doNotAllowUpdates = YES;
__weak __typeof(self)weakSelf = self;
[self.collectionView performBatchUpdates:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.collectionView reloadItemsAtIndexPaths:@[indexPath]];
}
} completion:^(BOOL finished) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
strongSelf.dataSource.doNotAllowUpdates = NO;
}
}];
Beachten Sie, dass die BOOL
Membervariable, doNotAllowUpdates
, ist eine Variable, fügte ich hinzu, dass verhindert jede Art von Datasource/Collection Updates, während ein Anruf zu performBatchUpdates läuft.
Ich suchte online nach Diskussionen darüber, ob wir das weakSelf/strongSelf-Muster in performBatchUpdates
verwenden sollten, aber haben nichts speziell zu dieser Frage gefunden.
Ich bin froh, dass ich diesem Bug auf den Grund gehen konnte, aber ich würde einen intelligenteren iOS-Entwickler lieben, der mir dieses Verhalten erklärt, das ich sehe.
Es wäre interessant zu sehen, ob Sie herausfinden könnten, ob der Aktualisierungsblock oder der Completion-Block den Retain-Zyklus verursacht hat. Wie Sie sagen, sollten beide ihren Block nicht dauerhaft festhalten - ich kann nur annehmen, dass, wenn die Sammlungsansicht aus ihrem Superview entfernt wird, keine Batchaktualisierungen mehr ausgeführt werden und der Komplettierungsblock nicht aufgerufen oder freigegeben wird. Es ist meiner Meinung nach ein Radar wert. – jrturton
@jrturton Ahh das scheint die wahrscheinlichste Erklärung! Ich werde sehen, ob ich dies im Debugger basierend auf dieser Einsicht wiederholen kann. – esilver
@jrturton leider nicht in Debugger repro ... es scheint, als ob beide Blöcke, zumindest, immer aufgerufen werden. Vielleicht werden die Interna die Blöcke nicht nivellieren, wenn die Kündigung in der Mitte aufgerufen wird? – esilver