【问题标题】:iOS State preservation and restoration when data shared between view controllers视图控制器之间共享数据时的 iOS 状态保存和恢复
【发布时间】:2014-04-29 17:12:55
【问题描述】:

我是第一次实现 iOS 状态保存和恢复,所以这个问题对于更有经验的人来说可能很明显!

我有一个故事板,其中包含通往各种场景的多条路径。例如,用户可以从场景 A 开始到场景 B,然后到场景 C,或者用户可以直接到场景 C。

在 View Controller A 中创建一个“大”NSDictionary,然后将其传递给 View Controller B,然后通过 prepareForSegue 方法传递给 View Controller C(或直接传递给 C)。

我相信我能够恢复视图控制器 A 中的 NSDictionary,但是如何为视图控制器 B 和/或 C 获取它而不是制作额外的副本?

【问题讨论】:

  • 您的字典中有多少键/值?
  • 查看NSUserDefaults 或单例模式,然后查看NSCoding 协议。随着您的应用程序的逻辑从字典中管理其状态发展而来,您可能希望将状态保留在自定义对象或单例类中。如果是前者,您可以将该对象写入磁盘,或写入NSUserDefaults 以根据需要提取。如果您使用单例方法,您将在内存中拥有该实例,以便在需要时使用。无论如何,随着状态的复杂性增加,有很多方法可以管理状态。
  • NSDictionary 非常庞大且复杂。虽然我可以创建多个副本,但我很想知道如何避免它。

标签: ios uistoryboard uistoryboardsegue state-restoration


【解决方案1】:

这里应该不用担心内存。假设它看起来像这样:

- (void) prepareForSegue .... {
  nextViewController.dictionary = self.dictionary;    
}

我避免了细节,但重点是这是传递对 NSDictionary 的引用,而不是复制整个字典。这意味着您的所有视图控制器实际上将共享完全相同的字典。

所以他们不应该担心拥有一本大字典的副本。尽管您应该知道,如果视图控制器 B 确实更改了字典,这些更改将在所有其他视图控制器中受到影响。

希望这个答案。

【讨论】:

  • 是的,这正是正在发生的事情。那么在 nextViewController 的 decodeRestorableStateWithCoder: 方法中,是否可以从前一个视图控制器中获取(已经恢复的)NSDictionary?
  • 但 decodeRestorableState 应该仅在恢复已释放内存的应用程序时发生。不?你不应该在每次对不同的 viewController 执行 segue 时进行编码/解码
  • 是的,我明白了。但是,如果我的应用程序需要恢复(例如,系统终止),我正在尝试恢复使用 encodeRestorableStateWithCoder: 保存的视图控制器的数据。由于 iOS 使用恢复 ID(按顺序)为我的 Storyboard 中的每个视图控制器调用此委托方法,我希望视图控制器 B 引用视图控制器 A 中的 NSDictionary(刚刚恢复)。这有意义吗?
【解决方案2】:

因为视图控制器是按顺序恢复的,从根目录开始,我发现按照我的要求执行实际上非常简单。首先,在 Navigation 控制器中获取当前视图控制器的索引。由此,找出之前出现的视图控制器。 (如果我的 Storyboard 更复杂,我可以在前一个视图控制器上使用“isKindOfClass”来确定如何在其中获取 NSDictionary。)

例如:

- (void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
    [super decodeRestorableStateWithCoder:coder];

    // get current index of views in navigation controller
    int index = [[self navigationController].viewControllers indexOfObject:self];

    if (index == 1) {
        ViewControllerA *view = [[self navigationController].viewControllers objectAtIndex:index - 1];
        self.dict = view.someDict;
    }
    else if (index == 2) {
        ViewControllerB *view = [[self navigationController].viewControllers objectAtIndex:index - 1];
        self.dict = view.arrayOfDict[0];
    }
}

【讨论】:

    猜你喜欢
    • 2019-03-23
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多