由于直接写入plist文件的局限性,不能够存储自定义对象,所以就有了归档,NSString、NSDictionary、NSArray、NSData、NSNumber等类型的对象,可以直接用NSKeyedArchiver进行归档和恢复,因为它们内部实现了NSCoding协议,比如NSString实现了NSSecureCoding,而NSSecureCoding实现了NSCoding协议,不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以,而归档和解档的过程很像我们在URL请求的时候进行encode和decode的过程,而在归档自定义对象的时候,如果子类对象也需要归档那么,在子类对象实现encodeWithCoder和initWithCoder方法的时候要先调用父类的encodeWithCoder和initWithCoder。
归档的特点:
//获取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;
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];
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方法强制写入。
原文:http://blog.csdn.net/richerg85/article/details/20456969