Property List 数据持久化

plist 文件, 全名是 Property List 因为文件以 .plist 结尾,所以通常叫做 plist 文件。最外层的 type 只有 字典和数组两种类型。

支持的数据类型

NSData NSString NSNumber NSDate NSArray NSDictionary 全部都是不可变的

创建方式

1.手动创建

barneyzhaoooo

2.代码创建

NSString *plistPath = [NSString stringWithFormat:@"%@/Documents/%@", NSHomeDirectory(), @"test.plist"];

数据写入

    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    
    [dic setObject:@"ceshi"
            forKey:@"name"];
    
    [dic setObject:@"12"
            forKey:@"age"];
    
    [dic setObject:@"man"
            forKey:@"sex"];
    
    [dic writeToFile:plistPath
          atomically:YES];

读取

1.手动创建的读取方式

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"download"
                                                             ofType:@"plist"];
        NSMutableArray *dataArr = [[NSMutableArray alloc] initWithContentsOfFile:filePath];

2.代码创建的读取方式,依然通过路径获取

        NSString *plistPath = [NSString stringWithFormat:@"%@/Documents/%@", NSHomeDirectory(), @"test.plist"];
    
//        NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
        NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
    
        NSLog(@"%@",data);

打印结果:

2017-06-01 11:32:28.126 AYDataBaseDemo[1989:518382] {
    age = 12;
    name = zhangsan1111;
    sex = man;
}

root 层是什么类型,就用什么类型来解析。

删除 plist 文件

    NSFileManager *fileMger = [NSFileManager defaultManager];
    
    NSString *filePath = [NSString stringWithFormat:@"%@/Documents/%@", NSHomeDirectory(), @"test.plist"];
    NSLog(@"%@",filePath);
    
    if ([fileMger fileExistsAtPath:filePath]) {// 如果存在就删除
        NSError *err;
        [fileMger removeItemAtPath:filePath
                             error:&err];
    }

修改,删除,覆盖

新建一个数组写入之前的路径,再次打印发现数据已经被覆盖。

NSMutableArray *arr = [NSMutableArray array];
    [arr addObject:@"1"];
    [arr addObject:@"2"];
    [arr addObject:@"3"];
    [arr writeToFile:plistPath
          atomically:YES];
    
    NSMutableArray *arrRead = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
    NSLog(@"%@",arrRead);

打印结果:可以发现数据已经变成了 1 2 3

2017-06-01 14:23:17.545 AYDataBaseDemo[2595:818062] {
    age = 12;
    name = ceshi;
    sex = man;
}
2017-06-01 14:23:17.546 AYDataBaseDemo[2595:818062] (
    1,
    2,
    3
)

所以 plist 文件的修改和删除单条数据其实是先 读取 copy 原数据,修改后整体重新覆盖写入,并不是之前期待的类似关系型数据库的操作,但是存一些简单的用户信息,基本设置还是很适合的,毕竟杀鸡焉用宰牛刀~

判断路径下指定文件是否存在

if ([[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
        NSLog(@"exist!");
    }

NSUserDefaults 系统封装了一个单例的类,方便使用

系统提供了单例的初始化方式

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

简单写入数据,强制同步 synchronize 并非必要

    [defaults setObject:@"barney"
                 forKey:@"firstName"];
    [defaults setInteger:18
                  forKey:@"Age"];
    
    [defaults synchronize];

读取

    NSString *firstName = [defaults objectForKey:@"firstName"];
    NSInteger age = [defaults integerForKey:@"Age"];
    
    NSLog(@"firstName = %@,age = %ld",firstName,(long)age);

还可以利用归档存储自定义 model

model 类实现 NSCoding 协议

@interface OneModel : NSObject <NSCoding>

@property (nonatomic, copy) NSString *addid;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *salary;

@end
@implementation OneModel

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.addid
                  forKey:@"addid"];
    [aCoder encodeObject:self.age
                  forKey:@"age"];
    [aCoder encodeObject:self.name
                  forKey:@"name"];
    [aCoder encodeObject:self.salary
                  forKey:@"salary"];
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        self.addid = [aDecoder decodeObjectForKey:@"addid"];
        self.age = [aDecoder decodeObjectForKey:@"age"];
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.salary = [aDecoder decodeObjectForKey:@"salary"];
    }
    
    return self;
}

@end

model 类声明并且赋值

OneModel *model = [[OneModel alloc] init];
    [model setAddid:@"1"];
    [model setName:@"barney"];
    [model setAge:@"18"];
    [model setSalary:@"1000"];

转换 model 类为 data 类型

    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model];
    [defaults setObject:data forKey:@"model"];

获取 data 还原回 model

    NSData *getData = [defaults objectForKey:@"model"];
    OneModel *getModel = [NSKeyedUnarchiver unarchiveObjectWithData:getData];

    NSLog(@"addid = %@ name = %@ age = %@ salary = %@",getModel.addid,getModel.name,getModel.age,getModel.salary);

成功打印

2017-06-01 15:49:52.534 AYDataBaseDemo[3040:1210973] addid = 1 name = barney age = 18 salary = 1000

这种数据持久化的方式用在小小的项目上还好,稍大稍复杂的项目通常会使用 SQLite 。或者是 CoreData。


参考资料:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.简介 数据持久存储是一种非易失性存储,在重启动计算机或设备后也不会丢失数据。持久化技术主要用于MVC模型中的m...
    公子无礼阅读 5,628评论 0 4
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,216评论 4 61
  • 1、 沙盒概念基本介绍 iOS 应用程序只能在该 app 的文件系统中读取。这个默认的 app 文件系统就是我们说...
    Laughingg阅读 7,753评论 2 10
  • 一个失落的男人,,,,该怎么活着
    纳兰无痕阅读 1,202评论 0 0
  • 20161007,终于回家,开心之旅结束。谢谢美丽的校长!谢谢美少女般的主席!谢谢大家的陪同! 成长记录:亲爱的叶...
    铭玮阅读 1,768评论 0 0