NSUserDefaults.standardUserDefau

2020-10-17  本文已影响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还没更新,导致读取到的还是以前的环境变量值。

修改方法

上一篇 下一篇

猜你喜欢

热点阅读