数据持久化方案一----NSUserDefaults(偏好设置)

2019-03-02  本文已影响0人  雨_田

一、NSUserDefaults是专门用来存储App配置信息的,一般不要在偏好设置中保存其他数据。是一个plist,名字为Bundle identifier名字,如cn.com.xiaoli.XLDemo.plist

二、存储位置
沙盒--> Library-->Preferences: *.plist

NSString *preferencePath = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES).firstObject;

三、支持持久化类型
NSArray(含NSMutableArray)、NSDictionary(含NSMutableDictionary)、NSData(含NSMutableData)、NSString(含NSMutableString)、NSNumber、NSDate、BOOL。但存储的对象全是不可变的。

四、NSUserDefaults的域:
UserDefaults数据库中其实是由多个层级的域组成的,当你读取一个键值的数据时,NSUserDefaults从上到下透过域的层级寻找正确的值,不同的域有不同的功能,有些域是可持久的,有些域则不行。默认包含五个Domain,如下:
1、参数域( argument domain)有最高优先权
2、应用域(application domain)是最重要的域,它存储着你app通过NSUserDefaults set...forKey添加的设置
3、全局域(global domain)则存储着系统的设置
4、语言域(language-specific domains)则包括地区、日期等
5、注册域(registration domain)仅有较低的优先权,只有在应用域没有找到值时才从注册域去寻找
例如,当某个界面是第一次运行时,这时的key值(键)所对应的值还不存在,所以NSUserDefaults对象会使用默认值为0。但是对于某些设置,可能需要临时的、非0的默认值(如"出厂设置"),否则应用将无法正确的运行。一般默认值都是存放于注册域中。默认情况下,应用域是空的,没有键也没有值。当用户第一次修改某个设置时,相应的值会通过指定的键加入应用域。当通过NSUserDefaults对象获取某个设置的值时,该对象先会在应用域查找,如果没有,NSUserDefaults则会在注册域中查找并返回默认值。查询顺序:参数域 -> 应用域 -> 全局域 -> 语言域 ->注册域。

五、api使用方法(类似NSMutableDictionary)

//获取标准用户默认对象(配置为搜索当前应用程序搜索列表的NSUserDefaults的全局实例)
@property (class, readonly, strong) NSUserDefaults *standardUserDefaults;
//重置
+ (void)resetStandardUserDefaults;
// 用应用程序和当前用户的默认值初始化用户默认对象
- (nullable instancetype)initWithSuiteName:(nullable NSString *)suitename API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)) NS_DESIGNATED_INITIALIZER;
- (nullable id)initWithUser:(NSString *)username API_DEPRECATED("Use -init instead", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0));


//存
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName;
- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName;
- (void)setFloat:(float)value forKey:(NSString *)defaultName;
- (void)setDouble:(double)value forKey:(NSString *)defaultName;
- (void)setBool:(BOOL)value forKey:(NSString *)defaultName;
- (void)setURL:(nullable NSURL *)url forKey:(NSString *)defaultName API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

存完后要调用synchronize方法,如果没有调用,系统会根据I/O情况不定时刻地保存到文件中,会造成数据丢失。所以如果需要立即写入文件的就必须调用synchronize方法。

//取
- (nullable id)objectForKey:(NSString *)defaultName;
- (nullable NSString *)stringForKey:(NSString *)defaultName;
- (nullable NSArray *)arrayForKey:(NSString *)defaultName;
- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName;
- (nullable NSData *)dataForKey:(NSString *)defaultName;
- (nullable NSArray<NSString *> *)stringArrayForKey:(NSString *)defaultName;
- (NSInteger)integerForKey:(NSString *)defaultName;
- (float)floatForKey:(NSString *)defaultName;
- (BOOL)boolForKey:(NSString *)defaultName;
- (nullable NSURL *)URLForKey:(NSString *)defaultName API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

//删(同样调用synchronize方法)
// -removeObjectForKey: is equivalent to -[... setObject:nil forKey:defaultName]
- (void)removeObjectForKey:(NSString *)defaultName;

注册默认值

//将指定字典的内容添加到注册域
- (void)registerDefaults:(NSDictionary<NSString *, id> *)registrationDictionary;

//维护套间

//将指定的域名插入到接收方的搜索列表中
- (void)addSuiteNamed:(NSString *)suiteName;
//从接收器的搜索列表中移除指定的域名
- (void)removeSuiteNamed:(NSString *)suiteName;

返回包含搜索列表中域中所有键值对的联合的字典

- (NSDictionary<NSString *, id> *)dictionaryRepresentation;

维护易失性域

//易失性域名
@property (readonly, copy) NSArray<NSString *> *volatileDomainNames;
//返回指定的易失性域的字典
- (NSDictionary<NSString *, id> *)volatileDomainForName:(NSString *)domainName;
//为指定的易失性域设置字典
- (void)setVolatileDomain:(NSDictionary<NSString *, id> *)domain forName:(NSString *)domainName;
//从用户的默认值中移除指定的易失性域
- (void)removeVolatileDomainForName:(NSString *)domainName;


//维护持久域
//返回当前持久域名的数组(不推荐使用
- (NSArray *)persistentDomainNames API_DEPRECATED("Not recommended", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0));
//返回指定域默认值的字典表示形式
- (nullable NSDictionary<NSString *, id> *)persistentDomainForName:(NSString *)domainName;
//为指定的持久域设置字典
- (void)setPersistentDomain:(NSDictionary<NSString *, id> *)domain forName:(NSString *)domainName;
//从用户的默认值中移除指定的持久域的内容
- (void)removePersistentDomainForName:(NSString *)domainName;

//访问托管环境密钥

//返回一个布尔值,该值指示指定密钥是否由管理员管理
- (BOOL)objectIsForcedForKey:(NSString *)key;
//返回一个布尔值,该值指示指定域中的密钥是否由管理员管理
- (BOOL)objectIsForcedForKey:(NSString *)key inDomain:(NSString *)domain;

//域

//由所有应用程序所看到的默认值组成的域(全局域)
FOUNDATION_EXPORT NSString * const NSGlobalDomain;
//从应用程序的参数解析默认值组成的域(参数域)
FOUNDATION_EXPORT NSString * const NSArgumentDomain;
//由一组临时缺省值组成的域,其值可以由应用程序设置,以确保搜索始终是成功的(注册域)
FOUNDATION_EXPORT NSString * const NSRegistrationDomain;

//相关通知

//当用户默认数据中存储更多数据时
FOUNDATION_EXPORT NSNotificationName const NSUserDefaultsSizeLimitExceededNotification API_AVAILABLE(ios(9.3), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);

//当设置了云默认时,但没有登录iCloud用户
FOUNDATION_EXPORT NSNotificationName const NSUbiquitousUserDefaultsNoCloudAccountNotification API_AVAILABLE(ios(9.3), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);

//当用户更改主iCloud帐户时
FOUNDATION_EXPORT NSNotificationName const NSUbiquitousUserDefaultsDidChangeAccountsNotification API_AVAILABLE(ios(9.3), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);

//发布时,默认完成下载数据,无论是第一次设备连接到一个iCloud帐户,或当用户切换他们的主要iCloud帐户
FOUNDATION_EXPORT NSNotificationName const NSUbiquitousUserDefaultsCompletedInitialSyncNotification API_AVAILABLE(ios(9.3), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);

//在当前进程中更改用户默认值时发布
FOUNDATION_EXPORT NSNotificationName const NSUserDefaultsDidChangeNotification;

例子:

//1.获得NSUserDefaults文件
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//2.向文件中写入内容
[userDefaults setObject:@"qwert" forKey:@"testKey"];
//2.1立即同步
[userDefaults synchronize];
//3.读取文件
NSString *testKey = [userDefaults objectForKey:@"testKey"];
NSLog(@"%@", testKey);
//4.删除文件
[userDefaults removeObjectForKey:@"testKey"];
[userDefaults synchronize];
上一篇下一篇

猜你喜欢

热点阅读