NSUserDefaults 不写入磁盘

Posted

技术标签:

【中文标题】NSUserDefaults 不写入磁盘【英文标题】:NSUserDefaults not writing to disk 【发布时间】:2015-03-03 16:20:41 【问题描述】:

我有一个小的背景 Mac(菜单栏)应用程序,它使用一个简单值(字符串)的首选项。当我从 Xcode 启动应用程序时,它几乎总是会报告 pref 已设置,即使 plist 在 ~/Library/Preferences 中不存在。在不进行任何代码库更改的情况下,它似乎偶尔会在后续启动时写入 prefs 文件。它确实有一个正常运行的帮助应用程序,以及一个 Today 扩展,如果它重要的话。我试过使用 [defaults synchronize] 命令,它什么也没做。我还有其他运行良好的应用程序。我不会在我的项目中的其他任何地方访问或设置 NSUSerDefaults(包括绑定)

目前,我的应用没有沙盒化。

一些示例代码:

NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
[standardDefaults synchronize];
NSLog(@"value for key is %@", [standardDefaults valueForKey:@"firstTime"]);
//this always reports back as "Accepted" even when no pref exists 

if ([[standardDefaults valueForKey:@"first"] isEqualToString:@"Accepted"])

    NSLog(@"accepted");
    //always seen

else

    //rarely seen except in complete random times
    NSLog(@"first time");
    @try
    
        NSLog(@"alert");

        [standardDefaults setObject:@"Accepted" forKey:@"first"];
        [standardDefaults synchronize];            
    
    @catch (NSException *exception)
    
        NSLog(@"exception is %@", exception);
    
    @finally
    

    
 

UDPATE:我现在在非沙盒的新应用上看到了这一点。奇怪。我创建了一个全新的 mac/Cocoa 应用程序,并使用了以下代码:

- (void)viewDidLoad 

  [super viewDidLoad];

  NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
  [standardDefaults synchronize];
  NSLog(@"value for key is %@", [standardDefaults valueForKey:@"firstTime"]);

  if (![standardDefaults valueForKey:@"firstTime"])
  
    NSLog(@"settings value for key");
    [standardDefaults setValue:@"Whatever" forKey:@"firstTime"];
    [standardDefaults synchronize];
  

  NSLog(@"value for key is %@", [standardDefaults valueForKey:@"firstTime"]);


  // Do any additional setup after loading the view.

第一次,它报告为丢失。之后的每次尝试,tt 都会立即注册为 pref 存在并报告为“whatever”,即使 pref 文件绝对不存在。

【问题讨论】:

你不是在你的第一个 NSLog 中检查错误的键吗?不应该是“第一次”而不是“第一次”吗? 这里搞混了,但代码正确 【参考方案1】:

该文件通常由 cfprefsd 定期写入。每次你读/写你实际与 cfprefsd 对话的值,而不是磁盘上的文件。

当您同步时,它会导致 cfprefsd 再次获取您设置的值,但不能保证将其写入磁盘。

您所说的条件似乎表明首选项是第一次设置的,即使您没有看到文件出现在磁盘上,它也在读取值。这是预期的行为。

如果您想在编写之前测试重置首选项,您需要清除它们,使用类似:

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

我相信自从引入云首选项同步以来,文件不出现已成为一个更明显的问题。修改文件从未被认为是稳定的。

如果您想从命令行删除首选项,您应该使用defaults delete(不过,我手头没有 mac 可以为您提供确切的命令行)。

【讨论】:

以上是关于NSUserDefaults 不写入磁盘的主要内容,如果未能解决你的问题,请参考以下文章

应用退出时如何确保 NSUserDefaults 设置保存到磁盘?

NSUserDefaults读取和写入自定义对象

如何在我的应用加载之前从 NSUserDefaults 检索值...?

为啥 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用?

iOS 10,NSUserDefaults 不起作用

日志中的 NSUserDefaults 错误