我们通常使用NSUserDefaults来存储一些偏好设置和用户数据,直接使用[NSUserDefaults standardUserDefaults]的接口可以很方便地存取字符串、数值以及序列化的二进制数据。在多数情况下,这样操作问题不大,但当APP功能足够复杂模块足够多之后,总是使用[NSUserDefaults standardUserDefaults]的接口并不是一个好的选择。
实际上,[NSUserDefaults standardUserDefaults]操作的是APP沙箱中Library/Preferences目录下的以bundle id命名的plist文件。假设一个很复杂的APP,集成了很多SDK,这些SDK中或多或少的都会用到[NSUserDefaults standardUserDefaults]的接口,这样会带来以下几个问题:
- 各个SDK需要保证设置数据KEY的唯一性,以防止存取冲突;
- plist文件越来越大造成的读写效率问题;
- 无法便捷的清除由某一个SDK创建的NSUserDefaults数据;
针对这个问题,可以考虑使用initWithSuiteName接口。
- (nullable instancetype)initWithSuiteName:(nullable NSString *)suitename
这个接口的参数有四种情况:
- 传入nil
和[NSUserDefaults standardUserDefaults]一样,操作的是Documents/Library/Preferences目录下以bundle id命名的plist文件。
- 传入bundle id
无效,会返回nil。
- 传入App Groups配置中Group ID
会操作APP的共享目录中创建的plist文件,方便跨APP或宿主APP与扩展应用之间共享数据。
- 传入其他值
操作的是沙箱的Documents/Library/Preferences目录下以suitename命名的plist文件。
在大型APP的各个SDK开发中,只需要传入不同的suitename,即可操作不同的plist文件,可以解决上面的问题:
- 因为是操作的不同的plist文件,key自然是可以重复的;
- 将原本写入一个文件中的数据分散在不同的文件,提升存取效率;
- 可以通过removePersistentDomainForName接口移除指定suitename的全部数据,即清空指定plist文件而对其他文件没有干扰。