2013-07-18 3 views
9

Ich möchte die Statuswiederherstellung in meiner App durchführen, die keine Storyboards verwendet. Ich sehe, dass meine primäre App ViewController während der Statuswiederherstellung zweimal instanziiert wurde. Wie stellen Sie sicher, dass sie nur einmal erstellt wird?Korrekte Möglichkeit zum Erstellen und Wiederherstellen von UIViewControllern während der Statuswiederherstellung?

So wie ich den Fluss verstehen, application:willFinishLaunchingWithOptions und ein pplication:didFinishLaunchingWithOptions würde eine commonInit Methode verwenden, die Einrichtung würde die Anwendungen UIWindow und seine RootViewController. In meinem Fall ist der rootViewController ein UINavigationController mit einer Klasse namens "MyMainViewController", die als rootViewController der UINavigation dient.

Entlang dieser Seite bin ich auch mit willEncodeRestorableStateWithCoder bzw. didDecodeRestorableStateWithCoder. Aber es scheint, dass bis ich zu meinem didDecodeRestorableStateWithCoder komme, sehe ich zwei getrennte Instanzen von MyMainViewController erstellt.

Wie kann sichergestellt werden, dass nur ein UIViewController während der Wiederherstellung erstellt wird?

Reihenfolge der Anrufe bei der Restaurierung:

  • neue Instanz MyMainViewController erstellen (# 1) über Anwendung: willFinishLaunchingWithOptions:
  • MyMainViewController des viewControllerWithRestorationIdentifierPath: Coder aufgerufen und Mainviewcontroller wiederhergestellt wird (# 2)
  • Anwendung : didDecodeRestorableStateWithCoder: wird aufgerufen und UINavigationController wird decodiert und dem self.window
01 zugewiesen

Hier ist, was in meinem AppDelegate ich tue:

NSString * const kRootViewControllerKey = @"RootViewControllerKey"; 

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    [self commonInitWithOptions:launchOptions]; 
    return YES; 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    [self commonInitWithOptions:launchOptions]; 
    return YES; 
} 

- (void)commonInitWithOptions:(NSDictionary *)launchOptions { 

    static dispatch_once_t predicate; 
    dispatch_once(&predicate,^{ 

     // While this will be called only once during the lifetype of the app, when the process is killed 
     // and restarted, I wind up with an instance of MyMainViewController created first from here 
     // and then once again, during MyMainViewController's viewControllerWithRestorationIdentifierPath:coder 
     // that's invoked later on. 

     UIViewController *rootViewController = [MyMainViewController alloc] init]; 
     UINavigationController *aNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

     aNavController.navigationBarHidden = YES; 
     aNavController.restorationIdentifier = NSStringFromClass([aNavController class]); 

     UIWindow *aWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
     aWindow.rootViewController = aNavController; 
     aWindow.restorationIdentifier = NSStringFromClass([window class]); 

     self.window = aWindow; 
    }); 
} 

// Encode app delegate level state restoration data 
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder { 
    [coder encodeObject:self.window.rootViewController forKey:kRootViewControllerKey]; 
} 

// Decode app delegate level state restoration data 
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder { 

    // Find the preserved root view controller and restore with it 
    UINavigationController *navControlller = [coder decodeObjectForKey:kRootViewControllerKey]; 

    if (navControlller) { 
     self.window.rootViewController = navControlller; 
    } 

} 
+0

Haben Sie jemals eine Lösung dafür gefunden? Ich stoße auf genau das gleiche Problem, weil mein View-Controller zweimal gestartet wird. – djibouti33

+0

Nein - hat es nie getan. Ich bin mir nicht sicher, wie ich damit umgehen soll, da ich nicht mit Storyboards arbeiten kann. –

Antwort

0

Es gibt immer nur sein, eine Instanz meiner Stammansicht Klasse soll, so dass ich es gelöst durch eine Klassenmethode zu alloc das Hinzufügen und die Klasse init nur einmal und das Rück sonst den Wert:

+ (id) initOnce { 
    static id view_ref; 

    if(!view_ref) 
     view_ref = [[UIViewController alloc] init]; 

    return view_ref; 
} 

Nun, wenn die Klasse initialisiert wird über [UIViewController initOnce], die gleiche Ansicht Referenz immer wird zurückgegeben, ob während willFinishLaunchingWithOptions oder viewControllerWithRestorationIdentifierPath.

+0

Auch können Sie nicht einfach die .restorationClass auf der Root-Ansicht und UIKit State Wiederherstellung scheint "The Right Thing" zu tun. – jasonjwwilliams