OC语言基础十一:数据持久化存储,plist文件,NSUserDefaults,归档和解档

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仍然存在这个问题。 菜单选项现在是硬件…删除所有内容和设置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值