NSUserDefaults 在导航时不保存

Posted

技术标签:

【中文标题】NSUserDefaults 在导航时不保存【英文标题】:NSUserDefaults doesn't save upon navigation 【发布时间】:2014-05-28 14:59:43 【问题描述】:

我正在使用情节提要在 Xcode 5 中为 iPad (ios7) 开发应用程序。我有一个奇怪的问题:

我通过按下按钮调用此方法:

-(void)navigateToProjectsPage 
// Save the currently open subject
NSString *detailDescription;
NSString *imageDescription;

// Get the information to be saved
detailDescription = _detailDescriptionTextView.text;
imageDescription = _imageDescriptionTextView.text;

// Create the 2 save keys
NSString *detailDescriptionKey = [NSString stringWithFormat:@"%@%@", [self.detailItem description], @"-detailDescription"];
NSString *imageDescriptionKey = [NSString stringWithFormat:@"%@%@", [self.detailItem description], @"-imageDescription"];

NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
[myDefaults setObject:detailDescription forKey:detailDescriptionKey];
[myDefaults setObject:imageDescription forKey:imageDescriptionKey];
[myDefaults synchronize];

// Close this project
[self performSegueWithIdentifier:@"projectsSegue" sender:nil];

// Show the selectSubjectBanner
_selectSubjectBanner.hidden = NO;

这应该保存一些新输入的数据,然后模态搜索到一个新的视图控制器。每当我关闭新的 VC 并返回到这个并尝试加载保存的项目时,它什么都不返回 - 就像它没有被保存一样。但是,如果我只是在多任务处理中一次关闭我的应用程序,而不按下按钮 - 它使用 AppDelegate.m 方法保存:

- (void)applicationDidEnterBackground:(UIApplication *)application

// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

// Save what the user entered
NSString *detailDescription;
NSString *imageDescription;

// Get the information to be saved
detailDescription = _detailViewController.detailDescriptionTextView.text;
imageDescription = _detailViewController.imageDescriptionTextView.text;

// Create the 2 save keys
NSString *detailDescriptionKey = [NSString stringWithFormat:@"%@%@", ([self.detailViewController.detailItem description]), @"-detailDescription"];
NSString *imageDescriptionKey = [NSString stringWithFormat:@"%@%@", [self.detailViewController.detailItem description], @"-imageDescription"];

// Save the data
[[NSUserDefaults standardUserDefaults] setObject:detailDescription forKey:detailDescriptionKey];
[[NSUserDefaults standardUserDefaults] setObject:imageDescription forKey:imageDescriptionKey];

有什么线索吗?

谢谢!

【问题讨论】:

【参考方案1】:

[self.detailItem description] 不太可能做你想做的事。它可能包括self.detailItem 的实例指针,它会在详细信息项更改时(甚至当您使用相同的详细信息项重新加载时)发生更改,因此您的密钥将不匹配。如果细节项有任何其他变化,也可能会产生影响。

用户默认值中的键通常应该有不错的静态键,您可以再次找到它们。

也看看你到目前为止添加了什么,登录[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]并搜索你的-detailDescription标签。

此外,在您的情况下,对这种短期样式存储使用用户默认值(无论如何都是这样)可能不是最好的。通过在字典中创建和存储(并在需要时作为属性传递)这些数据,您可以成为更好的服务器。

【讨论】:

[self.detailItem description] 是我在选择 UITableView 单元格时得到的项目 'Description' 是 NSObject 上的内置方法 - 你试过替换它吗? 具有不同名称的属性,例如“概览”。含义相同,但与现有方法不冲突。 但“detailItem”只是在 VC 的头文件中声明的一个 Id - 它不是自定义的 - 那么不同的方法会起作用吗? [detailItem description] 消息来自 Apple 的 MasterDetailTemplate - 所以我一直使用这种方法 你怎么看? @Wain【参考方案2】:

Wain 的回答是正确的。 detailItem 的描述类似于<UIClassName: 0x2ad7b00>。此外,您询问为什么导航时未保存您的数据。这是因为 detailItem 在您的详细视图控制器隐藏时被释放。当您的控制器再次显示时,detailItem 将再次分配,因此它会有不同的地址。因此,描述将不同。

但是,当您的应用程序进入后台时,详细视图控制器会留在内存中,并且 detailItem 的地址不会改变。

【讨论】:

我认为你误会了。当我完全退出应用程序时,将它向上滑动到多任务页面,当我回来时它仍然存在。并且 detailItem 是 UITableView 单元格的值(选择一个),所以当我再次点击该项目时应该重新加载【参考方案3】:

问题是旧信息在进入新的 UIViewController 后仍保留在系统中,而它应该被清除 - 编写了修复它的代码:

-(void)viewWillDisappear:(BOOL)animated 
[super viewWillDisappear:animated];
        // Clear as we're about to open a new project/exit
    _detailViewController.detailItem = @"";
    selectedSubject = @"";


您可能需要像我一样创建一个 BOOL(不在此代码 sn-p 中),以便在您使用 MasterDetail 模板时它不会干扰其他功能

【讨论】:

以上是关于NSUserDefaults 在导航时不保存的主要内容,如果未能解决你的问题,请参考以下文章

如何从命令行获取 NSUserDefaults

iOS 10,NSUserDefaults 不起作用

在 Xcode 5 中使用 NSUserDefaults 保存第二个打开的视图

在 iOS App 和 Todays Extension 之间共享数据

在 NSUserDefaults 和 Realm 中保存一个对象

NSUserDefaults 没有正确保存