【发布时间】:2013-07-18 22:30:02
【问题描述】:
我想在不使用故事板的应用中进行状态恢复。我看到我的主应用 ViewController 在状态恢复期间被实例化了两次 - 你如何确保它只创建一次?
按照我理解流程的方式,application:willFinishLaunchingWithOptions 和pplication:didFinishLaunchingWithOptions 将使用commonInit 方法来设置应用程序 UIWindow 及其 rootViewController。在我的例子中,rootViewController 是一个 UINavigationController,其中一个名为“MyMainViewController”的类用作 UINavigation 的 rootViewController。
除此之外,我还分别处理willEncodeRestorableStateWithCoder 和didDecodeRestorableStateWithCoder。但似乎当我到达我的didDecodeRestorableStateWithCoder 时,我看到创建了两个独立的 MyMainViewController 实例。
如何保证恢复时只创建一个UIViewController?
恢复期间的调用顺序:
- 通过应用程序创建新实例 MyMainViewController (#1):willFinishLaunchingWithOptions:
- 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;
}
}
【问题讨论】:
-
你找到解决方法了吗?我遇到了完全相同的问题,看到我的视图控制器被初始化了两次。
-
不——从来没有。我不知道如何解决它,因为我无法使用情节提要。
标签: ios state-restoration