ストーリー ボードを使用しないアプリで状態の復元を行いたいです。状態の復元中にプライマリ アプリの ViewController が 2 回インスタンス化されています。
application:willFinishLaunchingWithOptions私がフローを理解する方法は、アプリケーションの UIWindow とその rootViewController をセットアップするメソッドをpplication:didFinishLaunchingWithOptions使用することです。commonInit私の場合、rootViewController は、UINavigation の rootViewController として機能する「MyMainViewController」という名前のクラスを持つ UINavigationController です。
willEncodeRestorableStateWithCoderこれに加えて、ともそれぞれ扱ってdidDecodeRestorableStateWithCoderいます。しかし、myMainViewController に到達するまでにdidDecodeRestorableStateWithCoder、MyMainViewController の 2 つの別個のインスタンスが作成されていることがわかります。
復元中にUIViewControllerが1つだけ作成されるようにする方法は何ですか?
復元中の呼び出しの順序:
- application:willFinishLaunchingWithOptions を介して新しいインスタンス MyMainViewController (#1) を作成します。
- MyMainViewController の viewControllerWithRestorationIdentifierPath:coder が呼び出され、MainViewController が復元されます (#2)
- application:didDecodeRestorableStateWithCoder: が呼び出され、 UINavigationController がデコードされて self.window に割り当てられます
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;
    }
}