何时以及为什么要使用NSUserDefaults的synchronize()方法?

Jam*_*ill 9 performance nsuserdefaults ios

所以我看了一下NSUserDefaults的synchronize()方法上的苹果文档.见下面的参考:

https://developer.apple.com/reference/foundation/userdefaults/1414005-synchronize

该页面目前为:

因为此方法是定期自动调用的,所以只有在您无法等待自动同步时(例如,如果您的应用程序即将退出)或者您希望将用户默认值更新为磁盘上的内容,请使用此方法你没有做任何改变.

但是,我仍然不明白这个方法什么时候应该被调用?例如,每次用户更改应用程序的设置时是否应该调用它?或者我应该相信后台api会处理它?并且在内存中的设置更改后立即离开视图会导致更改丢失吗?

此外,如果调用synchronize()失败,导致用户设置无法正确更改?

此外,调用此方法的成本(性能,内存或其他)是多少?我知道它涉及从磁盘读取和写入磁盘,但这真的需要花费很多精力在手机上吗?

rma*_*ddy 31

关于用户默认值似乎存在很多混淆.这样想吧.它与您在整个应用程序中提供全局词典基本相同.如果您向全局字典添加/编辑/删除键/值,则该更改会立即显示在代码中的任何位置.由于这个字典在内存中,如果你的应用程序没有持久保存到文件,那么所有字典都会丢失.NSUserDefaults每隔一段时间自动将字典保存到文件中.

有一个synchronize方法的唯一原因是你的应用程序可以告诉NSUserDefaults"现在"持久保存字典而不是等待最终会发生的自动保存.

您需要这样做的唯一原因是因为您的应用可能会在下一次自动保存之前被终止(或崩溃).

在我自己的应用程序中,我调用的唯一地方synchronizeapplicationDidEnterBackground委托方法.这是为了确保在应用程序在后台终止时保留最新的未保存更改.

我认为很多混乱来自于在开发过程中调试应用程序.在开发期间,您使用调试器中的"停止"按钮终止应用程序并不罕见.很多时候,这种情况发生在最近的NSUserDefaults变化持续之前.因此,我习惯于在我想确保最新更新持久化之前,按下主页按钮,然后在调试器中终止应用程序之前将我的应用程序置于后台.

鉴于上述摘要,让我们回顾一下您的问题:

每次用户更改应用程序的设置时是否应该调用它?

不可以.如上所述,任何更改都会立即自动获得.

或者我应该相信后台api会处理它?

是的,相信自动持久性,但synchronize在您的应用进入后台时调用除外.

并且在内存中的设置更改后立即离开视图会导致更改丢失吗?

这没有效果.添加/编辑/删除键/值后NSUserDefaults,即可进行更改.

此外,如果调用synchronize()失败,导致用户设置无法正确更改?

唯一可以丢失更改的是,如果您的应用在最新更改持续之前被终止.synchronize当您的应用进入后台时调用可以解决大部分问题.唯一剩下的可能问题是你的应用程序崩溃了.任何尚未保留的未保存更改都将丢失.修复您的应用,以免崩溃.

此外,调用此方法的成本(性能,内存或其他)是多少?我知道它涉及从磁盘读取和写入磁盘,但这真的需要花费很多精力在手机上吗?

自动持久性在后台完成,它只是将字典写入plist文件.除非您不遵循建议,否则速度非常快.如果您滥用NSUserDefaults存储大量数据,速度会慢一些.


sas*_*tch 8

更新

正如预期的那样,它已被弃用,Apple Doc 中所述

同步()

等待对默认数据库的任何挂起的异步更新并返回;这种方法是不必要的,不应使用。

原答案

-不推荐使用同步,并将在未来版本中用 NS_DEPRECATED 宏标记。

-synchronize 阻塞调用线程,直到所有正在进行的设置操作完成。这不再是必要的。-synchronize 之前使用的替换取决于调用同步的意图。如果您同步...

— ...在读取以获取更新值之前:删除同步调用

— ...为了通知另一个程序读取而写入后:另一个程序可以使用 KVO 观察默认值而无需通知 — ...在非应用程序(命令行工具、代理或守护程序)进程中退出之前:调用 CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication)

— ...出于任何其他原因:删除同步调用


Mar*_*moy 5

Apple的文档synchronize()已经更新,现在读取:

等待默认数据库的任何挂起的异步更新并返回; 此方法是不必要的,不应使用.