【问题标题】:NSUserDefaults synchronize-methodNSUserDefaults 同步方法
【发布时间】:2012-03-27 17:20:56
【问题描述】:
 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"xxxxxxxx" forKey:@"name"];

[defaults synchronize];

我需要知道为什么我必须使用上述代码的最后一行 [defaults synchronize] ?使用它的目的是什么?是必须的吗?

【问题讨论】:

    标签: iphone cocoa-touch


    【解决方案1】:

    iOS 12 release notes你可以找到这个信息:

    NSUserDefaults 有几个错误修复和改进:

    删除了同步要求。不再需要使用 同步、CFPreferencesAppSynchronize 或 CFPreferencesSynchronize。 这些方法将在未来版本的操作系统中被弃用。

    如果您的目标设备是 iOS 12 或更新版本,根据上述发行说明,它应该可以在不调用 synchronize 的情况下工作。但是,如果您仍然支持 iOS 11 及更低版本,您可能仍需要调用 synchronize 方法。

    【讨论】:

      【解决方案2】:

      [default synchronize]; 的目的是让用户默认值立即写入磁盘。你不需要显式调用它,iOS 已经在适当的时候调用它。所以你可以删除那条线。其实每次设置默认值都调用synchronize是性能问题。

      在 iOS 7 之前,当应用程序转换到后台时,用户默认值总是同步的。从 iOS 7 开始,情况不再如此,因此您可能需要在应用代理的 applicationDidEnterBackground: 中调用 synchronize 或注册到 UIApplicationDidEnterBackgroundNotification 通知来执行此操作。

      来自the documentation for -[NSUserDefaults synchronize]:

      由于此方法会定期自动调用,因此仅当您无法等待自动同步(例如,如果您的应用程序即将退出)或您想要更新用户默认设置时才使用此方法磁盘,即使您没有进行任何更改。

      【讨论】:

      • 是的,没有那行代码你的代码也能正常工作。 iOS 稍后会自动将您的设置写入闪存。它最迟会在您的应用程序进入后台时写入。但在调试时要小心:如果您通过按“停止”按钮或应用崩溃时终止应用,则可能是尚未写入设置。
      • @Emil:错了,您可以立即再次访问密钥name。它已经在内存中,但还没有写入闪存。
      • 在iOS7中,我认为它不会在应用程序进入后台时将其写入flash,您必须在appdelegate进入后台时显式同步
      • @MeganZhou 我的猜测是Apple现在确实会不时同步,但它们在进入后台时不再同步。现在这意味着可能会发生以下情况:Apple 同步用户默认值,您写入新值,应用程序进入后台(用户默认值同步),应用程序被终止(例如由于内存压力) )。现在您的新值没有保存。因此,只需在应用程序进入后台时进行同步。 没有需要在任何其他时间致电synchronize!不要不要一直调用synchronize,这会影响应用性能。
      • 我不明白为什么你们在 'applicationWillTerminate' 而不是 'applicationDidEnterBackground' 期间不同步?因为 applicationWillTerminate 总是会在 kill time 被调用,这是我们要小心的。
      【解决方案3】:

      是的,您通过该行告诉您的系统使用您的新默认值上传 NSUserDefaults。

      您可以在这里找到所有信息:

      【讨论】:

        【解决方案4】:

        你不必再写那行了。

        来自更新的documentation的方法引用

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

        对解释做什么的方法的评论。

             /*!
             -synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release.
        
             -synchronize blocks the calling thread until all in-progress set operations have completed. This is no longer necessary. Replacements for previous uses of -synchronize depend on what the intent of calling synchronize was. If you synchronized...
             - ...before reading in order to fetch updated values: remove the synchronize call
             - ...after writing in order to notify another program to read: the other program can use KVO to observe the default without needing to notify
             - ...before exiting in a non-app (command line tool, agent, or daemon) process: call CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication)
             - ...for any other reason: remove the synchronize call
              */
             open func synchronize() -> Bool
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-01
          • 2013-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多