前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编码篇-持久化NSUserDefaults

编码篇-持久化NSUserDefaults

作者头像
進无尽
发布2018-09-12 18:11:37
1.1K0
发布2018-09-12 18:11:37
举报
文章被收录于专栏:進无尽的文章進无尽的文章

前言

NSUserDefaults类,以字典形式保存数据,IOS会自动把字典中的键值对转换成对应的XML文件(也就是plist文件),这个文件会被保存到APP的沙盒目录中(路径为Library/Preferences/plist文件名)。

NSUserDefaults为我们封装了读写plist文件的常用操作,我们可以使用它来保存一些简单的数据,比如系统配置,用户设置的参数之类的。

代码语言:javascript
复制
获取当前沙盒的Documents路径
  NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

查看当前沙盒文件

A文件内容

说明:上图中A(Bundle identifier.plist)是系统自动为我们创建的plist文件用来保存我们使用NSUserDefaults保存的数据。B为我们自己创建的的 plist文件,默认是在 Documents下。

值得注意的地方

  • NSUserDefault 支持的存储类型有:NSString、 NSNumber、NSDate、 NSArray、NSDictionary、BOOL、NSInteger、NSFloat等系统定义的数据类型以及他们的子类。
  • 自己创建的类 是不识别的 。
  • 字典中有 "<null>"这样的数据在使用NSUserDefault储存时会造成崩溃。 Attempt to insert non-property list object 报错原因,
  • 从NSUserDefaults返回的值是不可改变的,即便是你在存储的时候使用的是可变的值。例如你使用mutable string做为“MyStringDefault”的值,当你做使用stringForKey:方法获取的值,这个值仍然是不可变的。
  • NSUserDefaults是单例,同时也是线程安全的

NSUserDefaults 的使用

简便方法存取不同类型数据 由上边的例子可以看到一个方法-setInteger:,这跟常用的-setObject:相比设置类型更明确。其实,NSUserDefaults提供了若干简便方法可以存储某些常用类型的值,例如:

代码语言:javascript
复制
- setBool:forKey:
 - setFloat:forKey:
- setInteger:forKey:
 - setDouble:forKey:
  - setURL:forKey:
这将使某些值的设置更简单。

NSUserDefaults 常规使用方法封装

代码语言:javascript
复制
- (void)setUserDefaults :(id)obj :(NSString*)key;
{
    if (!obj) {
        return;
    }
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
    [[NSUserDefaults standardUserDefaults] setObject:obj forKey:key];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
- (id)getUserDefaults :(NSString*)key;
{
    return [[NSUserDefaults standardUserDefaults]objectForKey:key];
}
- (void)removeOneDefaults :(NSString *)key;
{
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
     [[NSUserDefaults standardUserDefaults] synchronize];
}

打印出系统中所有的 NSUserDefaults设置

代码语言:javascript
复制
NSDictionary* defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
NSLog(@"Defaults: %@", defaults);

registerDefaults方法的使用

- (void)registerDefaults:方法来初始化,这个方法会检查 NSUserDefaults是否已经存在了相同的key,如果存在就不会将其覆盖(相当于什么也没做),如果不存在就做保存操作。

简单举例来说明一下:

代码语言:javascript
复制
1.当第一次运行app时初始化了@"color":@"blue"
[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"color":@"blue"}];
这时NSUserDefaults里面'color'=='blue';

2.如果你在app中又重新设置了'color'=='red';

3.这时你重新运行一下你的app,仍然会调用[[NSUserDefaults standardUserDefaults] registerDefaults:@{@"color":@"blue"}];;但是此时,它检测到color这个key已经存在,并且'color'=='red',
  就不将blue写入NSUserDefaults中。此时依然是'color'=='red';

储存自定义对象

使用归档存储(真的储存)

一个NSUserDefaults的对象必须是属性表,这也就是说我们可以存储NSData,NSString,NSNUmber,NSDate,NSArray,NSDictionary这些实例。如果你想存储其他类型的对象,我们可以将其归档并创建一个NSData来实现存储。

让这个自定义类实现<NSCoding>协议中的 - (id) initWithCoder: (NSCoder *)coder方法和 - (void) encodeWithCoder: (NSCoder *)coder方法 然后把该自定义的类对象编码到NSData中,再从NSUserDefaults中进行读取。

代码语言:javascript
复制
#import <Foundation/Foundation.h>

@interface Test : NSObject
<NSCoding>
@property(copy,nonatomic)NSString *imageName;
@property(copy,nonatomic)NSString *ageStr;
@end

#import "Test.h"
@implementation Test
- (id) initWithCoder: (NSCoder *)coder
{
    if (self = [super init])
    {
        self.imageName = [coder decodeObjectForKey:@"imageName"];
        self.ageStr = [coder decodeObjectForKey:@"ageStr"];
    }
    return self;
  }
  - (void) encodeWithCoder: (NSCoder *)coder
  {
    [coder encodeObject:self.imageName forKey:@"imageName"];
    [coder encodeObject:self.ageStr forKey:@"ageStr"];
  }

@end

使用NSUserDefaults 储存

代码语言:javascript
复制
Test *bc = [[Test alloc] init];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSData *udObject = [NSKeyedArchiver archivedDataWithRootObject:bc];
[ud setObject:udObject forKey:@"myBusinessCard"];
udObject = [ud objectForKey:@"myBusinessCard"];
bc = [NSKeyedUnarchiver unarchiveObjectWithData:udObject];

储存 NSDictionary 后赋值给对象(假储存)

代码语言:javascript
复制
- (void)saveSchoolInfo:(NSDictionary *)info {
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  [userDefaults setObject:info forKey:@"school"];
  [userDefaults synchronize];
}

- (School *)getSchool {
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  NSDictionary *info = [userDefaults objectForKey:@"school"];
  School *school = [School objectWithKeyValues:info];
  return school;
}

值得注意的是,存入的NSDictionary里面必须不能包含 Null 对象,否则就会抛出异常

将数据储入plist文件中

写入文件方法:writeToFiel:对象调用方法

代码语言:javascript
复制
- (void)writeDataToPlist :(NSString  *)dataKey :(id)data
{
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *path=[paths    objectAtIndex:0];
    NSLog(@"path:%@",path);
    NSString *filename=[path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",dataKey]];
    //写入
    NSFileManager* fm = [NSFileManager defaultManager];
    [fm createFileAtPath:filename contents:nil attributes:nil];
    [data writeToFile:filename atomically:YES];
    if ([fm fileExistsAtPath:filename]) {
        NSLog(@"%@",[NSString stringWithFormat:@"%@文件写入成功",dataKey]);
    }
}
 返回的是文件的路径
- (NSString *)getDataFormPlist :(NSString  *)dataKey
{
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *path=[paths objectAtIndex:0];
    NSString *filename=[path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",dataKey]];
    return filename;
}

读取文件:每个类自带的能够根据文件路径读取文件的方法:[类名 + WithContentOfFiel],如下: WithOfContentFiel 后面跟的是文件的路径

代码语言:javascript
复制
NSString         :[NSString StringWithContentOfFile:]
NSArry           :[NSArry arrayWithContentOfFiel:]
NSDictionary     :[NSDictionary dictionaryWithOfContentFile:]
二进制流          :[NSData dataWithOfContentFiel:]

小结

NSUserDefaults的使用是比较简单的,本文旨在从总体上了解NSUserDefaults的本质和使用方法。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.11.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 值得注意的地方
  • NSUserDefaults 的使用
  • registerDefaults方法的使用
  • 储存自定义对象
  • 将数据储入plist文件中
  • 小结
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档