美文网首页
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

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