Ich versuche, die Statuswiederherstellung in einer App zu implementieren, die iOS 6+ und Storyboards verwendet, aber ich habe Probleme, einen Weg zu finden, doppelte Aufrufe an schwere Methoden zu verhindern.
Wenn ich die App einfach starte, muss ich die Benutzeroberfläche in viewDidLoad
:
Dies funktioniert in einer normalen, nicht-staatlich wiederhergestellten Welt. Jetzt habe ich die Wiederherstellung des Zustands hinzugefügt und nachdem ich einige Eigenschaften wiederhergestellt habe, muss ich die Benutzeroberfläche mit diesen Eigenschaften aktualisieren:
%Vor% Was jetzt passiert, ist, dass zuerst die Methode setupUI
von viewDidLoad
und dann wieder von decodeRestorableStateWithCoder:
aufgerufen wird. Ich sehe keine Methode, die ich überschreiben kann, die immer zuletzt genannt wird.
Dies ist die normale Reihenfolge der Methodenaufrufe:
Bei Verwendung der Statuswiederherstellung wird dies wie folgt aufgerufen:
Ich kann den Aufruf nicht auf setupUI
in viewWillAppear
setzen, weil er dann jedes Mal ausgeführt wird, wenn Sie in eine Ansicht zurückkehren.
Es wäre viel praktischer, wenn decodeRestorableStateWithCoder
BEFORE viewDidLoad
genannt würde, weil Sie dann wiederhergestellte Eigenschaften verwenden könnten. Leider ist das nicht der Fall, also ... wie kann ich verhindern, dass ich die Arbeit in viewDidLoad
erledige, wenn ich weiß, dass ich es gleich danach in decodeRestorableStateWithCoder
nochmal machen muss?
Wenn Sie die Statuswiederherstellung programmatisch durchführen (d. h. keine Storyboards verwenden), können Sie + viewControllerWithRestorationIdentifierPath:coder:
verwenden, den View-Controller dort initalisieren und alles verwenden, was Sie vom Coder benötigen, um Ihre Initialisierung vor dem ViewDidLoad durchzuführen.
Ich habe festgestellt, dass der Versuch, die Wiederherstellung des Zustands zu implementieren, in meinem Code zu schlechten Programmierpraktiken geführt hat, wie zu viel in viewDidLoad
zu packen. Auch wenn dies funktioniert (wenn Sie keine Storyboards verwenden), besteht die andere Möglichkeit darin, die Einrichtung der View-Controller neu zu gestalten. Anstatt ein Flag zu verwenden, verschieben Sie Codeteile in ihre eigenen Methoden und rufen Sie diese Methoden von beiden Orten auf.
Aus dem Buch "Programmieren von iOS 9: Tauchen Sie tief in Ansichten, View-Controller und Frameworks" Seite 386-387
Die bekannte Reihenfolge der Ereignisse während der Wiederherstellung des Zustands ist wie folgt:
application:shouldRestoreApplicationState:
application:viewControllerWithRestorationIdentifierPath:coder:
viewControllerWithRestorationIdentifierPath:coder:
, um die Kette herunterzufahren viewDidLoad
, um die Kette herunterzufahren; möglicherweise verschachtelt mit dem Vorstehenden
decodeRestorableStateWithCoder:
, um die Kette herunterzufahren application:didDecodeRestorableStateWithCoder:
applicationFinishedRestoringState
, um die Kette herunterzufahren Sie wissen immer noch nicht, wann viewWillAppear:
und viewDidAppear:
ankommen werden oder ob viewDidAppear:
überhaupt ankommen wird. Aber in applicationFinishedRestoringState
können Sie Ihren View-Controller und Ihre Schnittstelle zuverlässig konfigurieren.
Ja, es wäre in der Tat schöner, wenn -decodeRestorableStateWithCoder:
vor -viewDidLoad
aufgerufen würde. Seufz.
Ich habe meinen View-Setup-Code (der vom wiederherstellbaren Zustand abhängt) in -viewWillAppear:
und in dispatch_once()
anstelle einer booleschen Variablen verschoben:
Die Dokumentation besagt, dass "Ansichten nicht mehr unter Bedingungen mit wenig Arbeitsspeicher gelöscht werden", also sollte dispatch_once
für die Lebensdauer des View-Controllers korrekt sein.
Eine Korrektur zum MixedCase-Fluss (was sehr hilfreich war, danke), der tatsächliche Anruffluss ist ein bisschen anders:
Dies ist die normale Reihenfolge der Methodenaufrufe:
awakeFromNib
viewDidLoad
viewWillAppear
viewDidAppear
Bei Verwendung der Statuswiederherstellung wird dies wie folgt aufgerufen:
viewControllerWithRestorationIdentifierPath (entschlüsselt alle Daten, die für einen normalen Start benötigt werden)
awakeFromNib
viewDidLoad
viewWillAppear
viewDidAppear
decodeRestorableStateWithCoder (dekodieren Sie wiederherstellbare Zustandsdaten und legen Sie Ihre Controller-Benutzeroberfläche fest)
Tags und Links ios state uiviewcontroller