文章目录
plist
plist是OC持久化存储的一种手段,还有NSUserdefaults,相当于用户偏好设置,归档和存档,数据库操作。
plist的根节点必须是字典Dictionary 或者数组Array类型。
plist文件是xml数据格式,是一种标记语言,是一组一组的标签组成的。只不过编辑器为了编辑方便和显示直观,就使用了一种比较清晰的树状结构进行文件数据的展示。
数据写入plist文件
atomically参数,为YES,会先把数据写到一个文件副本中,当数据全部写入之后,再放到目录里的文件里面,文件是可以进行覆写操作的,所以当前目录已经有个文件了,最好是用YES,因为可以保证不会因为文件写入中断而导致原文件的损坏,是非常有必要的。
NSArray *array=@[@"one",@"two",@"three"];
[array writeToFile:@"/Users/chao/Desktop/plist/test.plist" atomically:YES];
NSDictionary *dict=@{@"name":@"Tom"};
[dict writeToFile:@"/Users/chao/Desktop/plist/test1.plist" atomically:YES];
plist文件种取出数据
NSArray *resultArray=[NSArray arrayWithContentsOfFile:@"/Users/chao/Desktop/plist/test.plist" ];
NSLog(@"%@",resultArray);
NSDictionary *resultDict=[NSDictionary dictionaryWithContentsOfFile:@"/Users/chao/Desktop/plist/test.plist" ];
NSUserDefaults
用户偏好设置,用户基本信息和配置信息的存储和读取。
拿到NSUserDefaults的对象
是单例对象,只会创建生成一次,通过它来进行数据保存,这个数据就是对当前工程全局可用的。
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
写数据
NSString *string=@"www.baidu.com";
[defaults setObject:string forKey:@"website"]//是字典的方法,所以这个文件的根节点是字典类型,forkey的参数不要写成中文,最好写成英文。
[defaults synchronize];调用同步操作的方法,为了保证数据能立即同步到文件当中。
读数据
就是字典的操作方法。
NSString *resultString=[defaults objectForKey:@"website"];
NSLog(@"%@",resultString);
NSInteger m_runCount=[defaults integerForKey:@"runCount"];
移除已经添加过的keyvalue
[defaults removeObjectForKey:@"website"];
移除全部记录
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
或者
// 先将其转化为字典,然后用forin遍历删除即可
NSUserDefaults *defatluts = [NSUserDefaults standardUserDefaults];
NSDictionary *dictionary = [defatluts dictionaryRepresentation];
for(NSString *key in [dictionary allKeys]){
[defatluts removeObjectForKey:key];
[defatluts synchronize];
}
保留指定记录,删除其他的全部
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
NSDictionary* defaults = [defs dictionaryRepresentation];
for (id key in defaults) {
if (![key isEqualToString:@"firstLaunch"]) {
[defs removeObjectForKey:key];
[defs synchronize];
} else {
NSLog(@"%@",[defs objectForKey:key]);
}
}
打印所有键值对
里面有很多内容,有一些程序本身的信息,
NSDictionary *dict=defaults.dictionaryRepresentation;
NSLog(@"%@",dict);
归档和解档
plist文件,NSUserDefaults都是操作的系统提供的类型,如果要自定义一个对象来进行数据的持久化存储,就需要用到归档和解档。
归档:对数据编码的过程,直接去存储自定义的对象是十分复杂的,需要通过编码的方式,把自定义对象转换成文件可识别的二进制对象,oc当中用来表示二进制对象的就是NSData类。
解档:对数据反编码的过程
归档
编码的时候有一定的规则,当对对象进行编码的时候,要对对象中的属性一一进行编码,编码完成之后再对Person对象进行编码,这样才能把所有的数据的数据信息存入到文件,并且类要遵循协议
//Person.h
#import <Foundation/Foundation.h>
@interface Person:NSObject<NSCoding>
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign)NSUInteger age;
@property(nonatomic,copy)NSString *sex;
@end
编码
//Person.m
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_name forKey:@"name" ];
[aCoder encodeInteger:_age forKey:@"age" ];
[aCoder encodeObject:_sex forKey:@"sex" ];
}
反编码
重写,initWithCoder方法
//Person.m
-(instancetype)initWithCoder:(NSCoder*)aDecoder
{
self =[super init];
if(self){
_name=[aDecoder decodeObjectForKey:@"name"];
_age=[aDecoder decodeIntegerForKey:@"age"];
_sex=[aDecoder decodeObjectForKey:@"sex"];
}
return self;
}
使用
//main.m
#import "Person.h"
int main(int argc, const char *argv[]){
@autoreleasepool{
Person *person=[[Person alloc]init];
person.name=@"Tom";
perosn.age=20;
perosn.sex=@"male";
NSData *personData=[NSKeyedArchiver archivedDataWithRootObject:person];//归档对象,归档器NSKeyedArchiver
NSLog(@"personData:%@",personData);//结果是16进制表示
[personData writeToFile:@"/Users/chao/Desktop/归档/personData" atomically:YES];//因为是持久话存储,所以循环中归档只执行一次就够了。
//解档过程
personData=[NSData dataWithContentsOfFile:@"/Users/chao/Desktop/归档/personData" ];
Person *resultPerson=[NSKeyedUnarchiver unarchiveObjectWithData:personData];
}
}
如何在一个归档文件中存储多个对象
用NSMutableData对象先后拼接起来
#import "Person.h"
int main(int argc, const char *argv[]){
@autoreleasepool{
Person *person=[[Person alloc]init];
person.name=@"Tom";
perosn.age=20;
perosn.sex=@"male";
Person *person1=[[Person alloc]init];
person1.name=@"xiaoming";
person1.age=20;
person1.sex=@"female";
NSMutableData *mutableData=[NSMutableData data];
NSKeyedArchiver *archiver=[[NSKeyedArchiver alloc]initForWritingWithMutableData:mutableData];
[archiver encodeObject:person forKey:@"person"];
[archiver encodeObject:person1 forKey:@"person1"];
[archiver finishEncoding];//如过不去调用这个方法,那么一直是在归档中,系统是不会自动完成归档的。
//解档的时候根据相应的KEY去找到对应的类的DATA数据就行了。
使用注意
卸载重装app
预期的行为是,当删除应用程序时,该应用程序的NSUserDefaults也会被删除。
但是,从模拟器中删除应用程序时,不会删除NSUserDefaults。
从运行iOS8的物理设备中删除它们时,它们会被正确删除。
一个快速而恼人的解决方案是点击,iOS模拟器 - &gt; 重置内容和设置。
带模拟器10的Xcode 9.2仍然存在这个问题。 菜单选项现在是硬件…删除所有内容和设置