UI(十六)数据持久化和归档NSCoding序列化

#pragma mark---目录---

 1、两个目录:

①、沙盒 (有三个文件夹 docments temp library)

②、bundle 在运行的时候 只能读数据 写不进去数据

 2、读取路径方式

 bundle目录:[NSBundle mainBundle]

 根目录:NSHomeDirectory()

 tmp:NSTemporaryDirectory()


 ①、查找路径数组

NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)

 ②、找到指定路径

 取第一个或最后一个元素

 Documents:NSDocumentDirectory

 library:NSLibraryDirectory

 Caches:NSCachesDirectory


 读写文件

 数组 字典 字符串

 write

 ContentsOfFile


 [数组对象 writeToFile:path atomically:YES]

 [字典对象 writeToFile:path atomically:YES]

 [字符串对象 writeToFile:path atomically:YESencoding:NSUTF8StringEncoding error:nil]


 [NSArray arrayWithContentsOfFile:path]

 [NSDictionary dictionaryWithContentsOfFile:path]

[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]

 #pragma mark---正文---

 数据持久化:把闪存上的数据以文件的形式保存下来(保存到磁盘)它的目的是为了保存数据

 1、plist

 2、NSUserDefaults

 3、归档 NSCoding 序列化

 4、sqlite(数据库)

 5、coreData(苹果专有数据库)


 路径:文件存储的位置

 ios专有的沙盒机制:bandBox  IOS的应用程序里,每一个应用程序只能够读取写入本应用程序的沙盒目录

 沙盒的路径->应用程序根目录

 NSLog(@"%@",NSHomeDirectory());打印根目录


沙盒目录的组成:

 1、Documents:可以开放读取写入的权限->里面所有的文件都可以导出或者拖进去->不要放一些隐私的文件

 怎样打开? 

    info.plist文件里面添加 Application supports iTunes file sharing 把这个key对应的值改成YES就可以分享Documents目录

 2、Library:存放配置信息或者数据库资源文件

 3、tmp:临时文件存储的地方 隔一段时间会清除一次(可以设置)->不能放重要的文件(数据库)

 bundle目录:应用程序右键显示包内容的目录 不允许应用程序在运行的时候写入任何数据


 #pragma mark---查找各个目录路径的方式:---

 根目录:NSHomeDirectory()

 bundle目录:[NSBundle mainBundle]

 tmp目录: NSTemporaryDirectory()

 #pragma mark---查找特殊的几个目录---

 Library目录、Documents目录、NSCachesDirectory:

 (1)、找到根目录--NSHomeDirectory() 拼接到Library目录

 ①通过拼接字符串拼接路径

NSString *path = [NSHomeDirectory() stringByAppendingString:@"/Library"];

NSLog(@"%@",path);

 ②专门用于拼接路径的方式

 路径是以“/”来区分的 如果用拼接字符串的方式拼接路径就必须加“/”

 如果用拼接路径的方式拼接路径就不能加“/”

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"];

NSLog(@"%@",path);

 (2)、查找用户应用程序的范围 查找Library目录

 记:查找目录会得到一个数组 Search(查找)

 ① 先找到某个路径的数组

NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);


     NSSearchPathForDirectoriesInDomains(要查找的路径, 要搜索的区域范围, 是不是允许获得扩展的目录);

 ② 获得数组里面的第一个或者最后一个目录(只有一个元素),就是要查找的目录

 NSString *path3 = [pathList lastObject];

NSLog(@"%@",path3);


 #pragma mark---写入读取文件:---

 字典、数组都有读取写入文件的方法

 1、写入到plist文件里面

 2、

 数组读取文件

 arrayWithContentsOfFile:(NSString *)path

 initWithContentsOfFile:(NSString *)path

 数组写入内容

 - (BOOL)writeToFile:文件路径 atomically:(BOOL)useAuxiliaryFile

**atomically 如果设置成YES 不会直接写入到指定文件 先写入到一个临时文件 暂存一下 当写入完毕才会存入到指定文件 如果遇到(断电 闪退 来电话...)就会删除临时文件 不去写入到指定文件 防止写入数据不完整 在使用的时候出现崩溃

 如果设置成NO 不管任何情况 都会写入


 字典读取文件

 dictionaryWithContentsOfFile:(NSString *)path

 initWithContentsOfFile:(NSString *)path

 字典写入文件

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile


 字符串读取文件

  initWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error

 stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error


NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

 字符串写入文件

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error


 NSError *error;

[content writeToFile:path atomically:YESencoding:NSUTF8StringEncoding error:&error];

--------------------------------------------------------------------

#pragma mark---归档---

*归档->数据持久化的方式->加密(把文件加密《不是把数据加密》)

*归档分为:

 1、存储数据(编码、序列化、归档过程)

 2、读取数据(解码、反序列化、解归档过程)


*可以归档的对象:必须遵守归档协议(NSSecureCoding遵守NSCoding)、实现协议方法


*除了NSObject未实现归档协议 其他实现了协议的类 都可以归档(UIViewController、UIView...)


归档类名:NSKeyedArchiver

解归档类名:NSKeyedUnarchiver


*归档、解归档 都是通过key来实现的

*在归档、解归档的时候 key一定要对应(尽量和对象名相同)

#pragma mark-----归档的步骤--------

1、写存储归档文件的路径

NSArray *searchList = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);

 *归档文件的尾缀尽量用 .archiver

NSString *path = [[searchList lastObject]stringByAppendingPathComponent:@"list.archiver"];

2、准备要归档的数据

NSArray *list = @[@{@"name":@"小明", @"age":@(18), @"height":@(18.5)}];

3、开始归档

*把一个Object(支持归档)的数据 以归档的形式存储到指定位置

 + (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;

*支持归档协议的对象 系统帮忙对他进行了编码

 BOOL isSuccess = [NSKeyedArchiver archiveRootObject:list toFile:path];

 if (isSuccess) {

NSLog(@"%@",path);

    }

#pragma mark-----解归档的步骤------

1、归档文件路径

2、开始解归档

 + (nullable id)unarchiveObjectWithFile:(NSString *)path

    NSArray *list = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

#pragma mark---NSData二进制的类---

*NSData 二进制的类 可以把文件或者数据转成二进制的对象

#pragma mark---多种数据归档步骤---

1、存储路径

NSArray *searchList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

 NSString *path = [[searchList lastObject]stringByAppendingPathComponent:@"user.archiver"];

2、初始化一个可变的二进制对象 **NSMutableData 同时准备要归档的数据

NSString *name = @"mary";

 NSInteger age = 18;

 float height = 172.5;


 NSMutableData *Data = [NSMutableData data];

3、归档等待写入数据的二进制对象(要把二进制对象写入到文件)->让归档对象帮他写入


     NSKeyedArchiver *arc = [[NSKeyedArchiver alloc]initForWritingWithMutableData:Data];

4、使用归档对象 对要归档的数据进行编码(同时写入到二进制对象-系统帮咱们操作)(编码结束就会把编码后的数据写入二进制对象)

*编码:encode 解码:decode

*要用对应的数据类型进行编码

[arc encodeObject:name forKey:@"name"];

[arc encodeInteger:age forKey:@"age"];

[arc encodeFloat:height forKey:@"height"];

5、编码结束

*把编码之后数据写入到二进制对象

     [arc finishEncoding];

6、把二进制对象存储到指定位置

 BOOL isSuccess = [Data writeToFile:path atomically:YES];

 if (isSuccess) {

NSLog(@"%@",path);

#pragma mark---多种解归档---

 **decode 解码

- (instancetype)initForReadingWithData:(NSData *)data

1、归档文件路径

2、使用data读取数据 准备解归档data里面的数据

    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:[NSData dataWithContentsOfFile:path]];

3、解归档数据 用对应的数据类型接收

 NSString *name = [unarchiver decodeObjectForKey:@"name"];

 NSInteger age = [unarchiver decodeIntegerForKey:@"age"];

 float height = [unarchiver decodeFloatForKey:@"height"];

 NSLog(@"%@  %ld  %f",name,age,height);


#pragma mark---*自定义归档*---

自定义归档->有些数据不能归档->让他遵守归档协议(NSCoding)->

 归档、解归档都与第一种方式相同

userModel *user = [[userModel alloc]init];

user.name = @"江儿";

user.age = 18;

user.height = 165.5;


 NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"user.archiver"];

 BOOL isOK = [NSKeyedArchiver archiveRootObject:user toFile:path];

 if (isOK) {

NSLog(@"%@",path);

    }



 userModel *userMode= [NSKeyedUnarchiverunarchiveObjectWithFile:path];


 NSLog(@"%@ %ld %f",userMode.name,userMode.age,userMode.height);


当在归档位置(viewController中)调用[NSKeyedArchiver archiveRootObject:XXX toFile:XXX]; 会自动调用encodeWithCoder:这个代理方法

使用**归档方法对对象归档的时候 会调用这个方法

- (void)encodeWithCoder:(NSCoder *)aCoder{

    aCoder就是系统传过来的NSKeyedArchiver实例化出来的对象

[aCoder encodeObject:self.name forKey:@"name"];

[aCoder encodeInteger:self.age forKey:@"age"];

[aCoder encodeFloat:self.height forKey:@"height"];

}


使用**解归档方法对对象解归档的时候 会调用这个方法

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{

 只要是构造方法先把创建对象的方法补全

 //self = [super init];

 //if (self) {

 //}

 //return self;


 self = [super init];

 if (self) {

 当使用解归档方法的时候 系统会自动调用initWithCoder:这个方法 系统会帮咱们创建一个对象

 之前的对象的数据保存在 归档文件里面

 在解归档的时候 还原数据 并且把还原的数据赋值给这个对象->现在这个对象的数据跟原来归档的数据是一样的

 self.name = [aDecoder decodeObjectForKey:@"name"];

 self.age = [aDecoder decodeIntegerForKey:@"age"];

 self.height = [aDecoder decodeFloatForKey:@"height"];


    }


 return self;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容