ストーリー ボードを使用しないアプリで状態の復元を行いたいです。状態の復元中にプライマリ アプリの 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;
}
}