2013-07-18 12 views
9

Chciałbym przywrócić stan w mojej aplikacji, która nie używa tablic ogłoszeń. Widzę główną aplikację ViewController utworzoną dwa razy podczas przywracania stanu - w jaki sposób upewniasz się, że jest tworzona tylko raz?Prawidłowy sposób tworzenia i przywracania kontrolerów UIView podczas przywracania stanu?

Sposób Rozumiem przepływ, application:willFinishLaunchingWithOptions i pplication:didFinishLaunchingWithOptions użyłby commonInit metodę, która konfiguracji aplikacje UIWindow i jego rootViewController. W moim przypadku rootViewController jest UINavigationController z klasy o nazwie "MyMainViewController" służącej jako rootViewController UINavigation.

Po tej stronie obsługuję również odpowiednio willEncodeRestorableStateWithCoder i didDecodeRestorableStateWithCoder. Ale wydaje mi się, że zanim przejdę do mojego didDecodeRestorableStateWithCoder, widzę dwa osobne wystąpienia MyMainViewController.

Jaki jest sposób zapewnienia, że ​​podczas przywracania zostanie utworzony tylko jeden kontroler UIViewController?

Zamówienie połączeń podczas renowacji:

  • Tworzenie nowej instancji MyMainViewController (# 1) za pomocą aplikacji: willFinishLaunchingWithOptions:
  • MyMainViewController za viewControllerWithRestorationIdentifierPath: koder powoływać i MainViewController przywróceniu (2 #)
  • aplikację : didDecodeRestorableStateWithCoder: jest wywoływana, a sterownik UINavigationController dekodowany i przypisywany do self.window

Oto co robię w moim AppDelegate:

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

Czy kiedykolwiek znalazłeś jakąś poprawkę? Występuje dokładnie ten sam problem, ponieważ mój kontroler podglądu jest inicjowany dwa razy. – djibouti33

+0

Nie, nigdy nie. Nie jestem pewien, jak to obejść, ponieważ nie mogę się przenieść do używania storyboardów. –

Odpowiedz

0

Jest tylko kiedykolwiek miała być jedna instancja moim zdaniem główny klasy, więc rozwiązany poprzez wprowadzenie metody klasy do alloc i init klasę tylko raz oraz zwracania wartości inaczej:

+ (id) initOnce { 
    static id view_ref; 

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

    return view_ref; 
} 

teraz, gdy klasa jest inicjowany przez [UIViewController initOnce] samo odniesienie zawsze widok zostanie zwrócony, czy podczas willFinishLaunchingWithOptions lub viewControllerWithRestorationIdentifierPath.

+0

Ponadto, po prostu nie można ustawić .restorationClass w widoku głównym i przywracanie stanu UIKit wydaje się robić "The Right Thing". – jasonjwwilliams

Powiązane problemy