之前已经实现了通过NSUserDefaults去保存用户数据:

【已解决】iPhone/iOS中保存自定义对象(Custom Object/Custom Class)的数组(NSMutableArray/NSArray)到NSUserDefaults

以便程序退出后,下次重新打开,加载之前的数据。

但是现在继续调试的过程中,发现一个问题,那就是,有时候NSUserDefaults保存数据没成功,偶尔会失败,导致对于程序数据的改动,没有保存,重启app,改动失效,还是改动之前的效果。

比如,本来当前的列表是:

改动后变为:

对应内部的数据,已调用setObject:forKey:去保存到NSUserDefaults了。

但是关闭app后再重启,发现改动失效了,还是改动之前的效果:

但是更奇怪的是,去调试了很多次,结果偶尔发现,此改动是可以生效的,即修改后的数据,又是成功的保存到了NSUserDefaults。

【解决过程】

1.调试了很多次,期间,遇到很多很是无语的事情,Xcode中的调试功能,不是一般的垃圾啊。

想看个当前变量的值,结果却无法直接查看。

总之,Xcode的调试功能,真尼玛太垃圾了。

详细过程,参考:

【整理】Xcode中的调试功能,真尼玛太垃圾了!!!

2.最后经过折腾,在调试了半天后,突然想到,好像之前NSUserDefaults的官网介绍中,提到一个synchronize的问题。

所以就回去看:

NSUserDefaults Class Reference

然后找到了那句提示:

At runtime, you use an NSUserDefaults object to read the defaults that your application uses from a user’s defaults database. NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value. The synchronize method, which is automatically invoked at periodic intervals, keeps the in-memory cache in sync with a user’s defaults database.

所以,就又去看synchronize:

synchronize

Writes any modifications to the persistent domains to disk and updates all unmodified persistent domains to what is on disk.

- (BOOL)synchronize

Return Value

YES if the data was saved successfully to disk, otherwise NO .

Discussion

Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.

Availability
  • Available in iOS 2.0 and later.
See Also
Related Sample Code
Declared In

NSUserDefaults.h

所以,就可以去代码中试试了。

3.添加了synchronize后,代码变为:

1
2
3
4
5
6
7
8
- ( void )saveBirdSightingList{
     //save data
    NSData *encodedCurBirdSightingList = [NSKeyedArchiver archivedDataWithRootObject:self.masterBirdSightingList];
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     [defaults setObject:encodedCurBirdSightingList forKey:@ "BirdSightingList" ];
      
     [defaults synchronize];
}

然后结果就解决了NSUserDefaults偶尔不工作的问题。

每次新的改动的数据,都可以得到同步,所以即使程序立刻退出,则变动也可以得到及时保存。下次重启程序,则也可以恢复得到最新的数据了。

【总结】

NSUserDefaults偶尔不工作,无法保存改动的数据的原因是,NSUserDefaults的机制是,过一段时间,会自动调用自己的函数synchronize去同步数据的。

而如果你是遇到和我此处类似的,改动数据后,就退出程序了,即在NSUserDefaults还没来得及synchronize之前就退出程序,就需要手动调用synchronize去保存数据了。

即,在需要的时候,手动调用NSUserDefaults去执行同步synchronize的动作,以及时保存(修改了的)数据。

NSUserDefaults偶尔/有时候保存数据会失败/失效的更多相关文章

  1. 解决NSUserDefault 偶尔保存数据无效

    一:情景 解决NSUserDefault 偶尔保存数据无效 今天用NSUserDefault保存一些少量的数据,但是发现 setObject时,有时成功!有时就是不成功! 二:解决方法 [[NSUse ...

  2. dede后台出现   保存目录数据时失败,请检查你的输入资料是否存在问题

    dede 5.7无法增加顶级/二级栏目,保存目录数据时失败,请检查你的输入资料是否存在问题!执行了SQL还是不行 解决档案:用正常可以添加栏目的,将E:\wamp\www\dededln\back(d ...

  3. Android(java)学习笔记182:保存数据到SD卡 (附加:保存数据到内存)

    1. 如果我们要想读写数据到SD卡中,首先必须知道SD的路径: File file = new File(Environment.getExternalStorageDirectory()," ...

  4. hibernate4无法保存数据

    hibernate4无法保存数据 author: hiu 以后都发文章我都备注一下作者了,hiu就是我了 红色字体更新日期:2014-07-08 初次使用hibernate4,使用getCurrent ...

  5. Android(java)学习笔记125:保存数据到SD卡 (附加:保存数据到内存)

    1. 如果我们要想读写数据到SD卡中,首先必须知道SD的路径: File file = new File(Environment.getExternalStorageDirectory()," ...

  6. EasyUI使用JSON保存数据

    目前来说,使用JSON保存数据比较方便,前台可以不用Test.aspx 页面,可以直接用Html页面,使用.aspx页面的弊端就不在这里熬述. 具体步骤如下: 1.新建一个Html页面,命名为Test ...

  7. Android开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制

    一.需求 做一个类似QQ登录似的app,将数据写到ROM文件里,并对数据进行回显. 二.截图 登录界面: 文件浏览器,查看文件的保存路径:/data/data/com.amos.datasave/fi ...

  8. IOS四种保存数据的方式

    在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: 1.NSKeyed ...

  9. 2016-1-7第一个完整APP 私人通讯录的实现 5:保存数据

    一:登陆界面 1):用户点击登陆按钮并成功登陆后,根据此时的开关情况选择是否保存数据,代码如下: "]) { [self performSegueWithIdentifier:@" ...

随机推荐

  1. 聊聊 Statsd 和 Collectd 那点事!

    StatsD 是由 Etsy 开发并发布的汇总和总结应用指标的一个简单的守护进程,近些年来发展迅速,已经变成了一个用于收集应用性能指标的统一的协议. 关于 Statsd 的使用已经有很多文章介绍过,所 ...

  2. ASP.NET Application_Error错误日志写入

    一个web项目开发已完成,测试也通过,但是,bug是测不完的,特别是在一个大的网络环境下.那么,我们就应该记录这些错误,然后改正.这里,我的出错管理页面是在global.asax里面的,利用里面的Ap ...

  3. [codility]PrefixMaxProduct

    Codility Certificate题目.求product最大值,product为长度*出现次数,例子"abababa"如下: "a", whose pro ...

  4. SPRING IN ACTION 第4版笔记-第五章BUILDING SPRING WEB APPLICATIONS-003-示例项目用到的类及配置文件

    一.配置文件 1.由于它继承AbstractAnnotationConfigDispatcherServletInitializer,Servlet容器会把它当做配置文件 package spittr ...

  5. Java中的比较

    Java SE.Java EE.Java ME区别 是什么: Java SE=Java Standard Edition=J2SE= Java标准版 Java EE=Java Enterprise E ...

  6. c#等待所有子线程执行完毕方法

    当我们在使用线程中,你会发现主线结束后子线程的结果才显示出来.现在我要等待所以子线程结束,然后在显示结果,怎么做呢? 方法如下: 1.使用 ManualResetEvent,代码如下:  using  ...

  7. 解决Dagger2和butterknife冲突

    dagger2 和 RxJava butterknife 以及 Retrofit使用起来非常酸爽 代码非常干净清晰 动手尝试 配置编译 DaggerAppComponent的时候 出现问题 配置dag ...

  8. BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演

    分析:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 然后对于求这样单个的gcd(x,y)=k的, ...

  9. 独立线程中实现QT GUI

    在网上搜集的资料: http://www.qtcentre.org/threads/16552-Starting-QT-GUI-in-a-seperate-Threadhttp://stackover ...

  10. OpenGL绘制自由落体小球

    OpenGL绘制自由落体小球 一.    程序运行的软硬件环境 本次设计在window10系统下进行,运用C++进行编写,在CodeBlocks环境下使用OpenGL进行设计. 所需环境配置分为2部分 ...