UIViewController 生命周期调用与状态恢复相结合

2023-12-27

我正在尝试在使用 iOS 6+ 和故事板的应用程序中实现状态恢复,但我在寻找防止重复调用繁重方法的方法时遇到问题。

如果我只是启动应用程序,那么我需要在中设置用户界面viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
}

这在正常的、非国家恢复的世界中运作良好。现在我添加了状态恢复,恢复一些属性后,我需要使用这些属性更新 UI:

- (void)decodeRestorableStateWithCoder:(NSCoder *)coder {
    [super decodeRestorableStateWithCoder:coder];
    // restore properties and stuff
    // [...]
    [self setupUI];
}

所以现在发生的事情是首先setupUI方法被调用自viewDidLoad,然后再次从decodeRestorableStateWithCoder:。我没有看到可以重写且始终最后调用的方法。

这是方法调用的正常顺序:

  • 从笔尖唤醒
  • viewDidLoad
  • 视图将出现
  • 查看是否出现

当使用状态恢复时,这被称为:

  • 从笔尖唤醒
  • viewDidLoad
  • 解码RestorableStateWithCoder
  • 视图将出现
  • 查看是否出现

我无法拨打电话setupUI in viewWillAppear因为这样每次你原生回到视图时它也会被执行。

如果decodeRestorableStateWithCoder之前被称为viewDidLoad因为这样你就可以使用恢复的属性。可悲的是事实并非如此,所以...我怎样才能阻止在viewDidLoad当我知道我需要重新做一遍decodeRestorableStateWithCoder就在之后?


如果您以编程方式进行状态恢复(即不使用故事板),您可以使用+ viewControllerWithRestorationIdentifierPath:coder:,在那里初始化视图控制器并使用编码器所需的任何内容来进行预 viewDidLoad 初始化。

+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder
{
    if ([[identifierComponents lastObject] isEqualToString:kViewControllerRestorationIdentifier]) {
        if ([coder containsValueForKey:kIDToRestore]) {
            // Can only restore if we have an ID, otherwise return nil.
            int savedId = [coder decodeIntegerForKey:kIDToRestore];
            ViewController *vc = [[ViewController alloc] init];
            [vc setThingId:savedId];
            return vc;
        }
    }

    return nil;
}

我发现尝试实现状态恢复在我的代码中显示出不良的编程实践,例如将太多内容打包到viewDidLoad。因此,虽然这可行(如果您不使用故事板),但另一个选择是重构您设置视图控制器的方式。不要使用标志,而是将代码片段移动到它们自己的方法中,并从两个地方调用这些方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIViewController 生命周期调用与状态恢复相结合 的相关文章

随机推荐

  • 如何在fragment中设置ContentView?

    现在我有了这个片段 我想将其与 setContentView 一起使用 但到目前为止我找不到如何使用 您可以在下面的代码中看到我的情况 我不想膨胀布局 我尝试将它与名为 SampleView 的视图一起使用 那么我该怎么做呢 public
  • 使用 Microsoft Visual C# 2010 Express 加载 DLL

    我使用 Microsoft C 2010 Express 和 Imperx 的 FrameLink Express 驱动程序 当我尝试在运行时加载 DLL 时 出现异常 无法加载 DLL VCECLB dll 无法加载指定的模块 成立 HR
  • 跨页面发布。在 Asp.net 中使用上一页是一个好习惯吗?

    我在 MSDN 上发现这篇文章谈论跨页面发帖 http msdn microsoft com en us library ms178139 aspx 我从未使用过 Page PreviousPage 但我认为这很有趣 你用它吗 这是一个好的
  • 在 monodroid 或 monotouch 中,我应该使用什么来代替 app.config 作为配置字符串?

    我想在 monodroid 项目中存储开发与生产连接字符串和配置字符串 我通常会将其作为应用程序设置存储在 web config 或 app config 中 但是在 monodroid 和 monotouch 项目中应该如何执行呢 我还希
  • 在从 Enum 填充的 ListPicker 中使用本地化字符串

    我正在填充一个ListPicker从一个Enum 例如 如果我有以下枚举 public enum Pets Dog Cat Platypus 我通过以下方式填充 ListPicker PetListPicker ItemsSource En
  • Ruby 元编程:无法将方法发送到模块

    例如 我有以下自定义类和模块 module SimpleModule def hello world puts i am a SimpleModule method end def self class hello world puts i
  • 导航栏显示在底部

    正如您从我添加的图片中看到的 我的导航栏显示在屏幕底部的表格视图下 我刚刚将导航栏拖放到该视图控制器上 这意味着我没有使用导航控制器 我不明白为什么会发生这种情况 我确信这是一个我所缺少的简单修复 图 2 是故事板视图 图 3 应用程序运行
  • Google Play 警告 Google Play 应用内结算实施不正确

    我刚刚收到来自 Google Play 的以下电子邮件 您好 Google Play 开发者 我们检测到您在此电子邮件末尾列出的应用程序是 不设置目标套餐调用应用内付费服务 为了意图 这可以使恶意包绕过 Play 商店计费系统并访问尚未购买
  • 给定一个未知长度的列表,通过仅扫描 1 次来返回其中的随机项

    给定一个未知长度的列表 通过仅扫描 1 次来返回其中的随机项 我的想法 类似的算法是储层采样 由其他人发布 但是 它太复杂了 因为它需要运行 rand 并在每次迭代中保留 k 个节点 有更好的解决方案吗 O n 时间和 O 1 空间 你为什
  • 使用Apple新的AudioEngine改变AudioPlayer声音的Pitch

    我目前正在尝试让 Apple 的新音频引擎与我当前的音频设置配合使用 具体来说 我正在尝试使用音频引擎改变音调 这显然是可能的这个帖子 https stackoverflow com questions 25333140 swift usi
  • glsl 和不同值的透视校正

    光栅化器是否使用透视校正对每个变化的顶点值 或在较新版本的 glsl 值中 走出 顶点着色器 进行插值 这取决于硬件吗 当发生裁剪时 裁剪顶点的值是如何计算的 我尝试撤消透视校正 并注意到被剪切的多边形的奇怪行为 我想更好地了解幕后发生的事
  • DataGridView - 使用DataPropertyName显示子元素属性

    让我们想象一下我有以下课程 public class Master public string MasterName Something public List
  • Flutter:我们如何将 Firebase 数据库与桌面应用程序一起使用

    我正在考虑使用 dart 和 flutter 开发一个桌面应用程序 但我不知道如何将 Firebase 数据库与其集成 任何建议将不胜感激 提前致谢 Use Firedart用于将 FIRebase 集成到基于桌面的 Flutter 应用程
  • python 中捕获性能异常

    我知道 python 中的异常处理速度很快try但就捕获量而言 可能会很昂贵 这是否意味着 try some code except MyException pass 比这个更快吗 try some code except MyExcept
  • numpy timedelta64 不显示分数

    我想将 847 小时转换为天 实际结果是 847 24 35 29 但是 numpy 仅显示 35 天 import numpy as np x np timedelta64 847 h x np timedelta64 x D print
  • PySpark 1.5 如何将时间戳从秒截断为最近的分钟

    我正在使用 PySpark 我在数据帧 canon evt 中有一个列 dt 这是一个时间戳 我正在尝试从日期时间值中删除秒 它最初是作为字符串从镶木地板中读入的 然后我尝试通过将其转换为时间戳 canon evt canon evt wi
  • WorkManager 尝试在 Application#onCreate 中将独特的定期工作排入队列时崩溃 [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将 WorkManager 与 Dagger 2 一起使用 将依赖项注入到工作人员中 我跟着本文 https proandro
  • 从 JList 取回数据

    我在谷歌上搜索一个从 JList 组件检索数据的解决方案 但没有找到任何解决方案 那么 Jlist 是否有一种返回其项目的方法 我不想要只选择一个 我想要整个清单 原因是我有这个方法可以根据列表框的选定值更新对话框的所有组件 我想用相同的方
  • 为什么我的 vba 代码将逗号视为新行?

    我有这段从文本文件中读取的代码 当行以 Q 开头时 它是一个问题 R 和 W 分别是读取到形状的错误和正确答案 但问题是 如果文本中的任何位置有逗号 我的 powerpoint 宏会将其视为新行 请帮忙解决这个问题吗 这是代码 Open A
  • UIViewController 生命周期调用与状态恢复相结合

    我正在尝试在使用 iOS 6 和故事板的应用程序中实现状态恢复 但我在寻找防止重复调用繁重方法的方法时遇到问题 如果我只是启动应用程序 那么我需要在中设置用户界面viewDidLoad void viewDidLoad super view