首先.沙盒目录常见的获取方式
1> Documents方式(保存需要持久化的数据,会备份)
2> Library/Caches(需要持久化数据,不会备份,缓存)
对应的方法:
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject];
- NSDocumentDirectory获得是Documents的路径
- NSCachesDirectory获得是caches的路径
- NSUserDomainMask 代表从用户文件夹下找
- YES 代表展开路径中的波浪字符”~”
- iOS 中只有一个目录跟传入的参数匹配,所以集合里只有一个元素
3> Library/Preferences(保存所有的偏好设置,会备份)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
一、XML属性列表(plist)归档
属性列表是xml文件,拓展名是plist
NSString,NSDictionary,NSArray,NSData,NSNumber等类型,
1.将OC数据类型写入plist文件中
// 将字典持久化到Documents/stu.plist文件
[dict writeToFile:path atomiacally:YES];
2.读取属性列表,恢复NSDictionary对象
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
总结:
NSDictionary-->writeToFile:atomiacally:-->"stu.plist"-->dictionaryWithContentsOfFile:NSDictionary
二、Preferences(偏好设置)
1.写入偏好设置数据
// 获得偏好设置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 写入数据
[defaults setObjects:@"wb" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBooL:YES forKey:@"auto_login"];
2.读取上次保存的设置
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults stringForKey:@"username"];
float *textSize = [defaults floatForKey:@"text_size"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
3.立刻同步
[defaults synchornize];
“注意”
UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘,所以调用set方法之后的缓存数据还没写入,程序就终止了,就会出现问题
三、NSKeyedArchiver归档(NSCoding)
1.两个归档和解码的方法
archiveRootObject:toFile:
unarchiveObjectWithFile:
- NSString NSDictionary NSArray NSData NSNumber可以直接进行归档和解码,其他自定义的必须遵守NSCoding协议才可以
2.一般的对象类型
重写:
encodeWithCoder:initWithCoder:两个方法
1> Person的接口
@interface Person : NSObject<NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) float height;
@end
2> Person的接口实现
@implementation Person
// 归档时调用,指定如何归档对象中每个实例变量
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeInt:self.age forKey:@"age"];
[encoder encodeFloat:self.height forKey:@"height"];
}
// 恢复对象使用,如何解码文件中的数据为对象的实例变量
- (id)initWithCoder:(NSCoder *)decoder {
self.name = [decoder decodeObjectForKey:@"name"];
self.age = [decoder decodeIntForKey:@"age"];
self.height = [decoder decodeFloatForKey:@"height"];
return self;
}
- (void)dealloc {
[super dealloc];
[_name release];
}
@end
3> 归档
Person *person = [[[Person alloc] init] autorelease];
person.name = @"MJ";
person.age = 27;
person.height = 1.83f;
[NSKeyedArchiver archiveRootObject:person toFile:path];
4> 恢复
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
注意:
继承对象中
[super encodeWithCoder:encoder];
self = [super initWithCoder:decoder];
3.NSData归档两个对象到同一文件(面试,归档多个对象)
1> 归档
//新建一块可变数据区
NSMutableData *data = [NSMutableData data];
// 将数据区连接到NSKeyedArchiver对象
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
// 开始存档对象,存档的数据都会存储到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
// 存档完毕(一定要调用这个方法)
[archiver finishEncoding];
// 将存档的数据写入文件
[data writeToFile:path atomically:YES];
2> 解码
恢复(解码)
// 从文件中读取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 根据数据,解析成一个NSKeyedUnarchiver对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢复完毕
[unarchiver finishDecoding];
“深复制”利用归档实现深复制
// 临时存储person1的数据
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];
// 解析data,生成一个新的Person对象
Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// 分别打印内存地址
NSLog(@"person1:0x%x", person1); // person1:0x7177a60
NSLog(@"person2:0x%x", person2); // person2:0x7177cf0