说明 :
如果把系统类NSUserDefaults比作为系统为我们佩带的轻型武器一点也不为过, 试想想当我们遇到小股敌人时, 我们还会用飞机坦克(创建文件, 数据库等)来消灭敌人吗? 如果这样做那也太耗资源了吧! 所以适当的用好系统为我们佩带的轻型武器 - NSUserDefaults十分关键并且方便.NSUserDefaults包含了持久域, 不稳定域, 套件(suite), 注册域等特性.
NSUserDefaults只适合存放少量的数据(官方文档中没有详细注明它的存储容量), 过大的数据需要使用文件和数据库来处理. NSUserDefaults类一般会存放一些个人信息, 设备的信息(配置文件)等
文章中尽量不使用或少使用封装, 目的是让大家清楚为了实现功能所需要的官方核心API是哪些(如果使用封装, 会在封装外面加以注释)
- 此文章由 @黑子 编写. 经 @春雨, @Scott 审核. 若转载此文章,请注明出处和作者
NSUserdefaults的创建方法及相关知识点
核心API
class: NSUserDefaults
涉及的主要API:
/** 1. 获取NSUserDefaults对象(系统中提供的单例) */
+ (NSUserDefaults *)standardUserDefaults
/** 2. 存取数据 .*/
- setObject:forKey:
- setInteger:forKey:
...
- setInteger:forKey:
- setInteger:forKey:
...
/** 3. 立即同步 .*/
- (BOOL)synchronize
/** 4. 同步更改之后, 将UserDefaults对象从内存中删除, 之后随即调用standardUserDefaults, 再次获取userDefault对象 */
+ (void)resetStandardUserDefaults
/** 5. 应用程序之间共享数据(当开发应用程序套件时) */
- (instancetype)initWithSuiteName:(NSString *)suitename
功能实现
思路
主要是针对NSUserDefaults的一些方法和在应用时需要注意的地方进行归纳
对于几种域的理解
1. NSUserDefaults保存数据的的存放位置及文件格式
NSUserDefaults是将数据保存在一个plist格式的文件中. 此plist文件路径为APP沙盒文件夹下/Library/Preferences/中
2. 存取数据
说明 : NSUserDefaults可以存放的数据类型有 : 基本类型(float, double, intgeter等), NSString, NSArray, NSDictionary, NSData, NSNumber, BOOL, NSURL类型. 存取数据一般都是对持久域进行的数据操作(默认).
注意 : 在对NSUserDefaults进行取数据时,它的返回值是不可变的. 即使向NSUserDefaults中存放一个可变类型的对象时, 取出时会返回一个不可变对象
在向NSUserDefaults中存放数据时, 不要存放NSNull类型的数据, 否则会crash. 所以当你向NSUserDefaults中存放数据之前最好判断你所存放的数据是否是NSNull类型的数据, 如果是可以将给类型数据转化为nil或者其他形式.
- (void)addData
{
/** 返回(找到)单例 */
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
/** 保存各种类型数据 */
[userDefaults setObject:@"张三" forKey:@"name"];
[userDefaults setInteger:21 forKey:@"age"];
[userDefaults setFloat:99.3 forKey:@"score"];
[userDefaults setDouble:170.66 forKey:@"height"];
[userDefaults setURL:[NSURL URLWithString:@"1944154449@qq.com"] forKey:@"email"];
NSArray *array = @[@"数学", @"语文", @"英语"];
[userDefaults setObject:array forKey:@"subject"];
NSDictionary *dic = @{@"父亲" : @"张毅", @"母亲" : @"刘岩"};
[userDefaults setObject:dic forKey:@"family"];
/**
* 保存数据
*
*系统也会周期性的调用此方法来为我们将数据存储到磁盘, 当你不想等待系统自动调用的话(比如app将要退出时, 或者你要立即更新数据时), 可以直接调用此方法.
*/
[userDefaults synchronize];
/** 返回对应域中的所有键值对 */
NSLog(@"%@", [userDefaults dictionaryRepresentation]);
}
3. 添加持久域
- 创建持久域会在 Library文件夹下的Perferences文件夹下生成plist文件, 且将存储的数据存放在磁盘中.
- 持久域 : 其实持久域无非就是他的生命周期和app的生命周期相同, 只要你不卸载app的话, 持久域就会存在, 卸载app, 持久域才会随之消失.
- (void)createPersistentDomain
{
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
/** 创建字典, 用来存放用户的爱好 */
NSDictionary *dic = @{@"ball" : @"football", @"book" : @"将夜"};
/** 添加持久域 */
[user setPersistentDomain:dic forName:@"hobby"];
/** 取出持久域 */
NSDictionary *dic1 = [user persistentDomainForName:@"hobby"];
NSLog(@"%@", dic1);
/** 删除持久域 */
[user removePersistentDomainForName:@"hobby"];
}
4. 创建添加不稳定域
- 不会生成plist文件, 且将数据存放在静态区
- 不稳定域 : 在你不退出程序时, 是可以取出不稳定域的. 但当你退出程序再进入程序时上次创建的不稳定域将不存在了;
这就是持久域与不稳定域的区别.
- (void)createvolatileDomain
{
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
/** 创建一个字典 */
NSDictionary *volatileDic = @{@"name" : @"zhangsan", @"age" : @"17"};
/** 添加不稳定域 */
[user setVolatileDomain:volatileDic forName:@"violatile"];
/** 取出不稳定域 */
NSLog(@"第一页violatile: %@", [user volatileDomainForName:@"violatile"]);
/** 删除不稳定域 */
[user removeVolatileDomainForName:@"violatile"];
}
5. 套件的创建及添加
套件的作用: 一个应用程序是不能访问或修改其他应用程序的偏好的.
当你在当前应用程序访问其他应用程序时, 系统读取数据的文件并不是被访问的应用程序的文件, 而是这个套件中的数据.
套件就是在开发应用程序扩展时,在扩展和包含应用程序之间共享偏好或其他数据的.
/** 创建一个套件在Library目录下的Perferences文件夹下 */
NSUserDefaults *suite = [[NSUserDefaults alloc] initWithSuiteName:@"nihao"];
/** 同理可以利用这个方法来添加套件 */
- (void)addSuiteNamed:(NSString *)suiteName
/** 利用该方法删除套件 */
- (void)removeSuiteNamed:(NSString *)suiteName
6. 注册域
- 注册域: 注册域的数据不会直接写入磁盘中.
- (void)registerDomain
{
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
NSDictionary *dic = @{@"name" : @"张三"};
[user registerDefaults:dic];
}