您的位置:首页 > 移动开发 > IOS开发

归档和偏好设置

2014-03-05 20:58 162 查看
由于直接写入plist文件的局限性,不能够存储自定义对象,所以就有了归档,NSString、NSDictionary、NSArray、NSData、NSNumber等类型的对象,可以直接用NSKeyedArchiver进行归档和恢复,因为它们内部实现了NSCoding协议,比如NSString实现了NSSecureCoding,而NSSecureCoding实现了NSCoding协议,不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以,而归档和解档的过程很像我们在URL请求的时候进行encode和decode的过程,而在归档自定义对象的时候,如果子类对象也需要归档那么,在子类对象实现encodeWithCoder和initWithCoder方法的时候要先调用父类的encodeWithCoder和initWithCoder。

归档的特点:

–支持复杂的数据对象,包括自定义对象。
–对自定义对象进行归档处理,对象中的属性需要是基本数据类型,或者是实现了NSCoding协议的对象实例;
–自定义对象的类也需要实现NSCoding;

归档和解档常用方法:

•encodeWithCoder:
–每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量
•initWithCoder:
–每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey:方法解码实例变量

归档数组:

//获取document目录
//NSUserDomainMask从用户文件夹开始找 YES代表代表展开路径中的波浪字符“~”
NSArray *documet=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *doc=documet[0];
//归档 如果归档为plist文件不需要用load的方式加载
NSString *ahPath=[doc stringByAppendingString:@"array.archive"];

NSArray *arr=@[@"book1",@"book2",@"book3"];
//归档
[NSKeyedArchiver archiveRootObject:arr toFile:ahPath];
//解档
NSArray *unarray= [NSKeyedUnarchiver unarchiveObjectWithFile:ahPath];
NSLog(@"array==%@",unarray);

归档自定义对象
@implementation Person

//归档
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInt:_age forKey:@"age"];
NSData *imageData=UIImagePNGRepresentation(_image);

[aCoder encodeObject:imageData forKey:@"imageData"];
}

//接档
-(id)initWithCoder:(NSCoder *)aDecoder{
self=[super init];
if (self) {
[self setName:[aDecoder decodeObjectForKey:@"name"]];
[self setAge:[aDecoder decodeIntForKey:@"age"]];
NSData *imageData=[aDecoder decodeObjectForKey:@"imageData"];
NSLog(@"%@",imageData);
[self setImage:[UIImage imageWithData:imageData]];
}
return self;
}

+(id)initPersonWithName:(NSString *)name age:(int)age image:(UIImage *)image{
Person *person=[[Person alloc]init];
[person setName:name];
[person setAge:age];
[person setImage:image];
return person;
}
@end


自定义对象子类对象
@implementation Student
-(id)initWithCoder:(NSCoder *)aDecoder{
self=[super initWithCoder:aDecoder];
if (self) {
_no=[aDecoder decodeObjectForKey:@"no"];
}
return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_no forKey:@"no"];
}

+(id)initPersonWithName:(NSString *)name age:(int)age image:(UIImage *)image no:(NSString *)no{
Student *stu=[[Student alloc]init];
[stu setNo:no];
[stu setAge:age];
[stu setImage:image];
[stu setName:name];
return stu;
}
@end


归档
NSArray *arry=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *doc=arry[0];
Person *person=[Person initPersonWithName:_nameText.text age:_ageText.text.intValue image:_iconView.image];
NSString *path=[doc stringByAppendingString:@"person.plist"];
[NSKeyedArchiver archiveRootObject:person toFile:path];

恢复
NSArray *arry=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dir=arry[0];
NSString *path=[dir stringByAppendingString:@"person.plist"];
Person *person= [NSKeyedUnarchiver unarchiveObjectWithFile:path];
_nameText.text=person.name;
_ageText.text=[NSString stringWithFormat:@"%d",person.age];
_iconView.image=person.image;

使用archiveRootObject:toFile:方法可以将一个对象直接写入到一个文件中,但有时候可能想将多个对象写入到同一个文件,那么可以使用NSData来归档对象,NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。可以使用[NSMutableDatadata]创建可变数据空间。



归档多个对象
NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [documents[0]stringByAppendingPathComponent:@"multiPersonInfo.plist"];

Person *person1=[Person initPersonWithName:@"san" age:_ageText.text.intValue image:_iconView.image];
Person *person2=[Person initPersonWithName:@"zhang" age:_ageText.text.intValue image:_iconView.image];
Student *stu=[Student initPersonWithName:@"lisi" age:10 image:_iconView.image no:@"89757"];

// 新建一块可变的数据区
NSMutableData *data = [NSMutableData data];

// 将数据区连接到一个NSKeyedArchiver对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];

// 开始存档对象,存档的数据都会存储到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];

// 存档完毕(一定要调用这个方法!!!)
[archiver finishEncoding];

// 将存档的数据写入文件
[data writeToFile:path atomically:YES];

恢复多个对象
NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [documents[0]stringByAppendingPathComponent:@"multiPersonInfo.plist"];
NSData *data = [NSData dataWithContentsOfFile:path];
// 根据数据,解析成一个NSKeyedUnarchiver对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
// 恢复对象
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢复完毕(一定要调用这个方法)
[unarchiver finishDecoding];


偏好设置

IOS应用都支持偏好设置,比如保存用户名、密码、字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能,每个应用都有个NSUserDefaults实例,通过它来存取偏好设置。

存储偏好设置
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:@"张三" forKey:@"userName"];
[defaults setInteger:10 forKey:@"age"];
[[NSUserDefaults standardUserDefaults]setObject:@"mimaya" forKey:@"password"];
//同步  如果不加会延迟
[defaults synchronize];
读取偏好设置
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *name=[defaults objectForKey:@"userName"];
NSLog(@"userName=%@",name);


注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘,应用程序就终止了,出现以上问题,可以通过调用synchornize方法强制写入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS 归档 恢复
相关文章推荐