iPhone 如何保存视图状态

Posted

技术标签:

【中文标题】iPhone 如何保存视图状态【英文标题】:iPhone How To Save View States 【发布时间】:2011-07-26 09:13:13 【问题描述】:

我已经开发 iphone 应用程序大约 3 个月了,有一些事情让我很困惑,我真的不知道如何解决它们。

我有一个导航控制器来控制我的应用程序中的视图,但是每个加载、使用然后推回的屏幕都会丢失所有信息,因为它似乎已被重新实例化...我认为这可能是内存管理问题?

但是我如何创建一个应用程序,在应用程序关闭之前导航并保留其视图中的所有信息。

谢谢:)

【问题讨论】:

视图控制器出栈时不是释放了吗? 【参考方案1】:

您可能没有保留对视图控制器的引用,问题是 UIVIewController 没有被释放。

将视图控制器设置为 ivar,当您将其压入堆栈时,您只会实例化一次。

// in .h
MyViewController *mVC;

// in .m
// maybe when the user selects a row in a tableview
if(mVC == nil) 
    // first time use, alloc/init
    mVC = [[MyViewController ....];

// then push on the stack
[self.navigationController ....];

当然不要忘记稍后发布。

【讨论】:

你能详细说明一下吗?我目前正在尝试使用 uitextfield 来做到这一点。按下视图控制器,在 uitextfield 中输入文本,弹出。然后弹回来看看文字是否还在。保存我在文本字段中输入的数据以使用 nsuserdefaults 或其他东西的唯一方法是什么? @MrPink - 你的控件状态没有被保存,因为UIViewController 被释放了。将状态保存到文件系统有问题吗?我不是那样理解的。 @MrPink - 如果您想在再次推送/弹出/推送时保留状态,UIViewController 一定不能被释放,为此,只需在您的班级中将其注册为 ivar ,当你需要推送它时,检查它是否是nil(第一次推送)并分配/初始化它。然后,当您将其从堆栈中弹出时,它不会被释放,除非您明确要求这样做。当你再次推送时,除非你在viewDidAppear: 中进行更新,否则你的控件状态将保持不变 我仍在努力让它发挥作用。我会继续摆弄你给我的所有信息,让你知道:) @MrPink - 独特的区别在于 VC 是您的自定义类的 ivar,而不是在您需要推送时声明/alloc/init【参考方案2】:

在这部分:

MyViewController *myViewController=[MyViewController alloc] initWithNibName:@"myView" bundle:nil];
[[self navigationController] pushViewController:myViewController animated:YES];
[myViewController release];

你可能会有这样的东西......相反,让你的 myViewController 成为一个类的属性,这样你就有了对它的引用。并删除[myViewController release]; 声明。

【讨论】:

错误答案。请参考上面的答案。像魔术一样工作。 @AbdulYasin,因为你可能是(在你的具体情况下)。如果您查看 op 问题,您会发现它太模糊,无法给出客观的答案。【参考方案3】:

您的应用可能会收到didReceiveMemoryWarning

在这种情况下,当调用超类时,框架会通过卸载所有当前未显示的视图来进行内存清理。这可以解释您所看到的行为。

要进一步检查,请在您的一个视图控制器中覆盖 didReceiveMemoryWarning 或在您的应用委托中覆盖 applicationDidReceiveMemoryWarning,并在其中放置一个断点。不要忘记适当地调用[super...],否则很快你的应用程序就会被杀死。通过这种方式,您应该看到的是视图在到达断点之前不会消失,并且会在断点之后消失。

如果假设是正确的,您应该找到一种方法将您的视图状态保存在viewDidUnload 并在viewDidLoad 中恢复它。另请参阅didReceiveMemoryWarning 参考。

【讨论】:

【参考方案4】:

尝试将数据保存在 NSUserDefaults 中,它太小或使用 plist 或太小,例如 5-10 个对象保存在 appDelegate 的某个变量中,如果它太大,请使用 sqlite 和保存像 xml 这样的文件的图像使用Document directory

【讨论】:

【参考方案5】:

UINavigationController 像堆栈一样工作:您在其上推送和弹出 UIViewController。这意味着当 UIViewController 被弹出时,它的保留计数会减 1,如果没有其他对象持有对它的引用,它将被释放。您可以通过在对象上调用 -retain 来避免 UIViewController 被释放,例如在您的 appDelegate 中。

【讨论】:

【参考方案6】:

您可以使用NSUserDefaults 来保存视图中 UIControls 的状态。

因此,每当您加载视图时,请将值设置为控件,使其看起来像是从我们离开的地方恢复。

【讨论】:

这就是我一直在做的。但我认为有一种更简单的方法,将整个视图保存或保存在内存中。每次推送和弹出页面时,它都必须访问我保存在 nsuserdefaults 中的内容?

以上是关于iPhone 如何保存视图状态的主要内容,如果未能解决你的问题,请参考以下文章

iPhone:如何将视图另存为图像??? (例如保存你画的东西)

当 iphone 应用程序进入后台或前台状态时,如何保存数据?

iPhone音频流 - 保存状态?

Iphone 5 状态栏被 React Native 覆盖

如何在iphone中保存缩放的图像

如何在iphone中更改下一个视图之前突出显示按钮?