0.数据本地化存储的方案选择
-
1.plist存储:只支持数组和字典的存储.plist文件也可以存储,但是会改变文件格式.
-
2.沙盒:
-
Documents:我们需要操作的目录,备份的时候也会自动备份.只有用户生成的文件、其他数据及其他程序不能重新创建的文件,应该保存在该目录下面,并将通过iCloud自动备份.
-
Library/Caches:缓存.可以重新下载或者重新生成的数据.
-
Library/Preference:偏好设置,由系统自动管理,适合比较少量的数据.
-
tmp:随时有可能被删除
-
1.plist存储
// 宏定义, 直接根据文件名称, 拼接文件的绝对路径,
#define kFilePath(fileName) ([NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:fileName])
#pragma mark - 写入文件
- (IBAction)writToFile:(id)sender {
NSString *filePath = kFilePath(@"cc.plist");
NSString *tempString = @"哈勒路亚";
// 把string 写到 文件当中
[tempString writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
#pragma mark - 读取内容,读取字符串的内容
- (IBAction)readFromFile:(id)sender {
NSString *tempString = [NSString stringWithContentsOfFile:kFilePath(@"cc.plist") encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", tempString);
}
2.用户偏好设置:preference
#pragma mark - 写入文件
- (IBAction)writToFile:(id)sender {
// 用户偏好
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 保存用户名
[defaults setObject:@"dd" forKey:@"name"];
// 保存年龄
[defaults setInteger:18 forKey:@"age"];
// 是否已婚
[defaults setBool:YES forKey:@"married"];
#warning 写入完数组之后, 要做一次同步
[defaults synchronize];
}
#pragma mark - 读取内容
- (IBAction)readFromFile:(id)sender {
// 取值
NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:@"name"];
NSInteger age = [[NSUserDefaults standardUserDefaults] integerForKey:@"age"];
BOOL married = [[NSUserDefaults standardUserDefaults] boolForKey:@"married"];
NSLog(@"name: %@, age: %ld, married: %d", name, age, married);
}
3.归档解档:
-
1.归档解档可以针对所有的对象 : 必须要遵守协议 NSCoding
-
2.归档原理:首先通过[NSKeyedArchiver archiveRootObject:XXX]来对对象进行归档,但是这个方法可没那么牛叉,类中的属性还是需要在自定义的类中 通过重写 - (void)encodeWithCoder:(NSCoder *)acoder;来实现的.
-
3.解档原理:首先通过[NSKeyedUnarchiver unarchiveObjectWithFile:...]返回一个解档出来的类对象,前面归档进去的是什么类型的对象,解档出来的对象就用什么类型去接收.同样,这个方法也没那么牛叉,具体的类的属性需要在自定义的类中重写- (instancetype)initWithCoder:(NSCoder *)aDecoder这个方法来实现.
-
4.如果存储的只是简单的数据类型,数组.字典啥的,那就不需要encodeWithCoder 和 initWithCoder了.
归档数组: [NSKeyedArchiver archiveRootObject:self.dataArray toFile:kFilePath(@"user.data")];
解档数组: NSMutableArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithFile:kFilePath(@"user.data")];
-
归档类的具体各个步骤实现的代码见下面:
#pragma mark - 写入文件
- (IBAction)writToFile:(id)sender {
// 归档 , 是写入到文件
// 创建对象
Person *person = [Person new];
person.name = @"dd";
person.age = 26;
/**
archiveRootObject: 要进行归档的对象,注意这里是针对一个类进行归档,但是这方法可不是真的那么厉害的.类中的属性还是需要自己在自定义的类中重写这个方法:- (void)encodeWithCoder:(NSCoder *)aCoder来实现对每个数据进行归档.
toFile: 文件路径
*/
[NSKeyedArchiver archiveRootObject:person toFile:kFilePath(@"user.data")];
}
/**
对数据进行归档
要对哪些属性进行归档
*/
- (void)encodeWithCoder:(NSCoder *)aCoder {
// 进行归档 也就是 把数据写入到文件
// 把_name 转为 NSCoder 这种类型的对象中的值
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
}
/**
进行解档数据
*/
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
// 解码, 把NSCoder 中的 key 对应的value 赋值给 和 key 值相当的属性
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}