Property List 数据持久化

作者: 漂泊海上的大土豆 | 来源:发表于2017-06-01 16:02 被阅读123次

    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。


    参考资料:

    相关文章

      网友评论

        本文标题:Property List 数据持久化

        本文链接:https://www.haomeiwen.com/subject/vljefxtx.html