美文网首页
NSUserDefaults.standardUserDefau

NSUserDefaults.standardUserDefau

作者: 林大鹏 | 来源:发表于2020-10-17 12:09 被阅读0次

因为项目里面有个切换环境的功能,切换环境后就会将选中的环境更新到用户偏好里面,然后退出app重新启动app就从用户偏好里面读取新的环境变量,然后请求的新环境地址

之前代码类似如下:

[FJFEnvironmentManager updateEnvironmentType:type];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
   exit(0);
});
+ (void)updateEnvironmentType:(FJFEnvironmentType)environmentType {
    [NSUserDefaults.standardUserDefaults setValue:@(environmentType) forKey:kFJJEnvironmentTypeKey];
    [NSUserDefaults.standardUserDefaults synchronize];
}

但存在有时候切换环境不成功问题,终于找到原因。

分析过程

首先从代码逻辑分析,觉得应该是没问题的,因为更新环境并保存到偏好设置,这里调用了[NSUserDefaults.standardUserDefaults synchronize];同步方法,因此应该是不存在环境没更新的问题。

接着通过查看偏好设置的plist文件,发现环境的更改并没有即时,存在延期情况,因此查看了synchronize函数。

/*!
 -synchronize is deprecated and will be marked with the API_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
 */

这里说synchronize这个函数已经被弃用,在将来版本使用中将使用API_DEPRECATED宏进行标志。

也就是说用户偏好的同步函数synchronize不在是同步阻塞的,而是系统内部定期去更新保存的。

用户偏好本质是一个plist文件,之所以多封装了一层,是因为多加了一层内存缓存操作,你对用户偏好的修改,会直接更新到内存缓存中,然后你立刻去读取,会直接从内存缓存中返回,然后内部在定时存储到plist里面。

也正是因为这样,我们更换环境,退出app,然后立刻重启,可能用户偏好的plist还没更新,导致读取到的还是以前的环境变量值。

修改方法

  • 最开始的时候想直接新建一个plist类来存储环境变量的值,然后操作plist文件来修改环境变量的值,但这种方法一来改动量有点大,二来用plist只存储一个环境变量有点浪费

  • 最终改用NSKeyedArchiver归档来存储环境变量值,这样只需新增路径,改变下存储和读取方法。

相关文章

  • NSUserDefaults.standardUserDefau

    因为项目里面有个切换环境的功能,切换环境后就会将选中的环境更新到用户偏好里面,然后退出app,重新启动app就从用...

网友评论

      本文标题:NSUserDefaults.standardUserDefau

      本文链接:https://www.haomeiwen.com/subject/dswxmktx.html