UIViewController-Lebenszyklusaufrufe in Kombination mit Statuswiederherstellung

8

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 :

einrichten %Vor%

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:

  • awakeFromNib
  • viewDidLoad
  • viewWillAppear
  • viewDidAppear

Bei Verwendung der Statuswiederherstellung wird dies wie folgt aufgerufen:

  • awakeFromNib
  • viewDidLoad
  • decodeRestorableStateWithCoder
  • viewWillAppear
  • viewDidAppear

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?

    
Kevin Renskers 07.08.2013, 15:22
quelle

7 Antworten

3
%Vor%

Danke an @calvinBhai für den Vorschlag.

    
Kevin Renskers 12.08.2013, 09:47
quelle
6

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.

%Vor%

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.

    
nevan king 31.08.2013 13:32
quelle
5

Komischerweise ist die Dekodiersequenz sogar anders und genau:

%Vor%

und es macht total Sinn so.

    
berbie 30.04.2014 08:49
quelle
2

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:

  1. application:shouldRestoreApplicationState:
  2. application:viewControllerWithRestorationIdentifierPath:coder:
  3. viewControllerWithRestorationIdentifierPath:coder: , um die Kette herunterzufahren
  4. viewDidLoad , um die Kette herunterzufahren; möglicherweise verschachtelt mit dem Vorstehenden
  5. decodeRestorableStateWithCoder: , um die Kette herunterzufahren
  6. application:didDecodeRestorableStateWithCoder:
  7. 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.

    
Mohammad Alavi 26.05.2017 20:19
quelle
0

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:

%Vor%

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.

    
jrc 04.10.2015 05:22
quelle
0

Hinzufügen zu berbie's Antwort,

Der tatsächliche Fluss ist:

%Vor%

Beachten Sie, dass Sie in initWithCoder den Wert self.restorationClass = [self class]; festlegen müssen, damit viewControllerWithRestorationIdentifierPath:coder: aufgerufen wird.

    
stephen 12.12.2016 04:16
quelle
-1

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)

    
Zeev Vax 29.04.2014 17:11
quelle

Tags und Links