2

我想在不使用情节提要的 iOS 6 应用程序中实现状态保存和恢复。我想要保存状态和恢复的主视图控制器是 UIViewController,它是 UINavigationController 的一部分。

我的视图控制器扩展了 UIViewControllerRestoration 协议。我想我正在实现所有必要的方法,但我没有看到模拟器对 encodeRestorableStateWithCoder 或 decodeRestorableStateWithCoder 的任何调用。

这是我的应用程序委托的样子:MyAppDelegate:

- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
    NSLog(@"shouldSaveApplicationState"); // seeing this in the debug window
    return YES;
}

- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
    NSLog(@"shouldRestoreApplicationState"); // seeing this in the debug window
    return YES;
}

- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"willEncodeRestorableStateWithCoder"); // seeing this in the debug window
}

- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"didDecodeRestorableStateWithCoder"); // seeing this in the debug window
}

我在调试窗口中看到了所有这些调用。这是我的 MyMainViewController(在应用程序挂起时可见)的样子:

@interface MyMainViewController : UIViewController <UIViewControllerRestoration>
@end

@implementation MyMainViewController

- (id)init {
    if (self = [super init]) {
        self.restorationIdentifier = @"MyViewControllerRestoreId";
        self.restorationClass = [self class];
    }
    return self;
}

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:frame];

    // Bunch of work to create my custom views
}

- (void)awakeFromNib {
    self.restorationClass = [self class];
}

// Expected a call to this method, but not seeing it in debug window
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents
                                                            coder:(NSCoder *)coder {
    NSLog(@"viewControllerWithRestorationIdentifierPath: %@", identifierComponents);

    MyMainViewController *vc = [[MyMainViewController alloc] init];
    vc.restorationIdentifier = [identifierComponents lastObject];
    vc.restorationClass = [MyMainViewController class];

    return vc;
}

// Expected a call to this method, but not seeing it in debug window    
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"encodeRestorableStateWithCoder");
    [super encodeRestorableStateWithCoder:coder];
}

// Expected a call to this method, but not seeing it in debug window    
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"decodeRestorableStateWithCoder");
    [super decodeRestorableStateWithCoder:coder];
}    
@end

我使用模拟器测试保存和恢复的方式:

1. Launch app in Simulator via Xcode
2. Invoke the Home key so App is now suspended. This where I see:
    shouldSaveApplicationState  
    willEncodeRestorableStateWithCoder
3. End the debugging session in XCode (Command .)
4. Start a new debug session of the app in XCode. I see:
    shouldRestoreApplicationState
    didDecodeRestorableStateWithCoder

我不确定我还缺少什么来完成这项工作。

4

3 回答 3

3

我遇到了完全相同的问题。结果,我需要在视图控制器上显式设置协议才能使用 restoreClass:

<UIViewControllerRestoration>

看起来你已经完成了,但最终为我做了。

于 2013-08-26T02:40:18.760 回答
2

此代码可能未运行:

- (id)init {
    if (self = [super init]) {
        self.restorationIdentifier = @"MyViewControllerRestoreId";
        self.restorationClass = [self class];
    }
    return self;
}

视图控制器的指定初始化程序是initWithNibName:bundle:,因此不能保证它init会被调用。另外,如果视图控制器来自 xib 或故事板,则这些方法都不会被调用。

你确实有一个awakeFromNib实现:

- (void)awakeFromNib {
    self.restorationClass = [self class];
}

如果视图控制器来自 xib 或故事板,它将运行,但在这种情况下,您忘记分配restorationID.

于 2013-09-02T22:50:12.597 回答
1

不知道这是否会有所帮助或有所作为,因为我自己只是在学习状态保存/恢复,但是您可以尝试从我正在学习的教程中获得一些东西。

如果您的 VC 在 TabBar 或 NavController 中,请确保它们也具有 restoreIdentifier。

于 2013-06-07T22:24:42.923 回答