码迷,mamicode.com
首页 > 其他好文 > 详细

数据存储与IO(二)

时间:2016-08-03 15:26:45      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

 

一、NSBundle资源包。

 

只要把文件拖到Xcode左边项目导航面板中,选择复制文件到项目中,该文件就包含进bundle中了。用[NSBundle mainBundle]获取应用程序包,常用的方法:

 

  • URLForResource:withExtension:根据资源名和扩展名获取对应的URL。
  • pathForResource:ofType:根据资源名和类型名获取对应的路径。
  • resourcePath:返回该NSBundle的子目录所包含资源的完整路径。

 

二、NSKeyedArchiver 、NSKeyedUnarchiver归档和恢复。

归档就是用某种格式把一个或多个对象保存到指定的文件中(把对象转化为可保存、可传输的数据流),在需要的时候再从文件中恢复它们(从数据流中恢复该对象)。

NSKeyedArchiver和NSKeyedUnarchiver继承自NSCoder。

1、NSKeyedArchiver的简单用法(适用于非自定义OC对象)。

  • 直接调用NSKeyedArchiver的archiveRootObject:toFile:类方法,指定单对象为root进行归档。
    1 NSDictionary *dict = @{@"xiaohong" : @"小红", @"xiaoming" : @"小明"};
    2 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    3 path = [path stringByAppendingPathComponent:@"dict.arch"];
    4 BOOL isSucc = [NSKeyedArchiver archiveRootObject:dict toFile:path];
  • 或者调用NSKeyedArchiver的archivedDataWithRootObject:类方法,把单对象转换成NSData的类型并返回,再写入本地或网络。
    1 NSDictionary *dict = @{@"xiaohong" : @"小红", @"xiaoming" : @"小明"};
    2 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
    3 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    4 path = [path stringByAppendingPathComponent:@"data.arch"];
    5 [data writeToFile:path atomically:YES];
  • 直接调用NSKeyedUnarchiver的unarchiveObjectWithFile:类方法进行恢复。
  • 1 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    2 path = [path stringByAppendingPathComponent:@"dict.arch"];
    3 NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
  • 或者调用NSKeyedUnarchiver的unarchiveObjectWithData:类方法,对已经归档成NSData的单对象进行恢复。
    1 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    2 path = [path stringByAppendingPathComponent:@"data1.arch"];
    3 NSData *data = [NSData dataWithContentsOfFile:path];
    4 NSDictionary *dicts = [NSKeyedUnarchiver unarchiveObjectWithData:data];

2、NSCoding协议的用法(适用于自定义OC对象)。

如果程序需要归档或恢复任意自定义对象,则该类必需实现NSCoding协议,并实现协议中定义的方法。

  • 1 #import <UIKit/UIKit.h>
    2 
    3 @interface HLPerson : NSObject <NSCoding>
    4 
    5 @property (copy, nonatomic) NSString *name;
    6 @property (assign, nonatomic) CGFloat height;
    7 
    8 @end
  • 归档该对象时,总会调用encodeWithCoder:方法,在此方法中分别调用NSCoder的encodeXxx:forKey:方法归档对应的成员变量。
  • 回复该对象时,总会调用initWithCoder:方法,在此方法中分别调用NSCoder的decodeXxxForKey:方法恢复对应的成员变量的值。
     1 #import "HLPerson.h"
     2 
     3 @implementation HLPerson
     4 
     5 - (void)encodeWithCoder:(NSCoder *)aCoder {
     6     [aCoder encodeObject:self.name forKey:@"name"];
     7     [aCoder encodeFloat:self.height forKey:@"height"];
     8 }
     9 
    10 - (instancetype)initWithCoder:(NSCoder *)aDecoder {
    11     self.name = [aDecoder decodeObjectForKey:@"name"];
    12     self.height = [aDecoder decodeFloatForKey:@"height"];
    13     return self;
    14 }
    15 
    16 @end

然后就可以像归档普通对象一样归档我们自定义的HLPerson对象了,参看1。

3、用NSData自定义归档。

前面的方法只能归档或恢复单个的OC对象,若要归档或恢复多个对象到单个文件中,则可以借助NSMutableData来创建NSKeyedArchiver或者NsKeyedUnarchiver对象。

(1)、归档步骤。

  • 以NSMutableData为参数创建NSKeyedArchiver对象。
  • 重复调用NSKeyedArchiver对象的encodeXxx:forKey:方法来归档所有需要归档到一个文件中的对象。
  • 调用NSKeyedArchiver对象的finishEncoding方法结束归档。
  • 保存该NSMutableData对象到本地或网络。
     1 HLPerson *person = [[HLPerson alloc] init]; // 自定义的对象需实现NSCoding协议
     2 person.name = @"hahh";
     3 person.height = 55;
     4 
     5 NSDictionary *dict = @{@"xiaohong" : @"小红", @"xiaoming" : @"小明"};
     6 NSArray *array = @[person, dict];
     7 CGFloat age = 12.5;
     8 
     9 NSMutableData *data = [NSMutableData data];
    10 NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    11 [arch encodeObject:person forKey:@"person"];
    12 [arch encodeObject:dict forKey:@"dict"];
    13 [arch encodeObject:array forKey:@"array"];
    14 [arch encodeFloat:age forKey:@"age"];
    15 [arch finishEncoding];
    16 
    17 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    18 path = [path stringByAppendingPathComponent:@"data.arch"];
    19 BOOL isSucc = [data writeToFile:path atomically:YES];

(2)、恢复步骤。

  • 以NSData为参数创建NSKeyedUnarchiver对象。
  • 重复调用NSKeyedUnarchiver对象的decodeXxx:forKey:方法来从一个文件中恢复所有归档过的对象。
  • 调用NSKeyedUnarchiver对象的finishEncoding方法结束恢复。
     1 NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
     2 path = [path stringByAppendingPathComponent:@"data.arch"];
     3 NSData *data = [NSData dataWithContentsOfFile:path];
     4 NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
     5 
     6 HLPerson *person = [unarch decodeObjectForKey:@"person"];
     7 NSDictionary *dict = [unarch decodeObjectForKey:@"dict"];
     8 NSArray *array = [unarch decodeObjectForKey:@"array"];
     9 CGFloat age = [unarch decodeFloatForKey:@"age"];
    10 
    11 [unarch finishDecoding];

延伸:归档会将整个对象转换成字节数据,包括该对象的所有成员变量,如果该成员变量指向另一个OC对象,则此OC对象也将一起被归档成字节数据。这就表明:当程序归档一个对象时,系统会把该对象关联的所有数据,都转换为字节数据。如果程序从这些字节数据中恢复对象,则恢复出来的对象和原来的对象相同,但在内存上的地址不同,这就实现了对象的深复制。

 

数据存储与IO(二)

标签:

原文地址:http://www.cnblogs.com/hankkk/p/5731627.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!