本篇文章使用NSKeyedArchiver和NSKeyedUnarchiver进行iOS的归档解档web
//沙盒根目录 NSString *docPath = NSHomeDirectory(); //完整的文件路径 NSString *path = [docPath stringByAppendingPathComponent:@"Documents/numbers.plist"]; NSArray *numbers = @[@"one",@"two"]; //将数据归档到path文件路径里面 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:numbers requiringSecureCoding:NO error:nil]; BOOL success = [data writeToFile:path atomically:NO]; if (success) { NSLog(@"文件归档成功"); } else { NSLog(@"文件归档失败"); }
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *path = [docPath stringByAppendingPathComponent:@"numbers.plist"]; NSData *data = [NSData dataWithContentsOfFile:path]; NSArray *numbers = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSArray class] fromData:data error:nil]; NSLog(@"numbers = %@", numbers);
上面的例子是将单个的数组或者单个字典归档到一个文件。其实咱们也能够将多个数组、字典、字符串、数组等内容归档到同一个文件里面去。数组
NSDictionary *dic = @{@"one":@"hello", @"two":@1}; NSInteger age = 10; NSMutableData *data = [NSMutableData data]; //建立归档对象,归档的数据须要写入data NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; //键值对形式存储归档数据 [arch encodeObject:dic forKey:@"Dic"]; [arch encodeInteger:age forKey:@"Age"]; //结束归档 [arch finishEncoding]; NSString *docPath = NSHomeDirectory(); NSString *manyPath = [docPath stringByAppendingPathComponent:@"Documents/manyData.plist"]; //将归档的数据写入文件 [data writeToFile:manyPath atomically:YES];
//建立解档对象 NSString *docPath = NSHomeDirectory(); NSString *manyPath = [docPath stringByAppendingPathComponent:@"Documents/manyData.plist"]; NSData *arrayData = [NSData dataWithContentsOfFile:manyPath]; NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc] initForReadingFromData:arrayData error:nil]; //根据键值获得对应数据 NSDictionary *dic = [unarch decodeObjectForKey:@"Dic"]; NSInteger age = [unarch decodeIntegerForKey:@"Age"]; //解档结束 [unarch finishDecoding]; NSLog(@"%@", dic); NSLog(@"%ld", age);
上面的例子,归档的内容都是系统Foundation框架提供的类以及一些基本的数据类型。
Foundation框架提供的类都是实现了NSCoding协议的,因此可以直接进行归档。
若是咱们本身自定义了一个类,例如Person类,是没法可以直接将这个类进行归档操做的。
若是想要对自定义的类建立出来的对象进行归档,咱们须要先实现NSCoding协议。app
@interface Student : NSObject <NSCoding> @property (nonatomic, strong) NSString *name; @property (nonatomic, assign) NSInteger grade; @end
#import "Student.h" @implementation Student //NSCoding协议方法:将须要归档的属性进行归档 - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeInteger:self.grade forKey:@"grade"]; [coder encodeObject:self.name forKey:@"name"]; } //NSCoding协议方法:将须要解档的属性进行解档 - (instancetype)initWithCoder:(NSCoder *)coder { if (self = [super init]) { self.name = [coder decodeObjectForKey:@"name"]; self.grade = [coder decodeIntegerForKey:@"grade"]; } return self; }
此处使用另外一种获取目录方法框架
//沙盒ducument目录 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; //完整的文件路径 NSString *path = [docPath stringByAppendingPathComponent:@"student.archiver"]; Student *student = [[Student alloc] init]; student.name = @"dd"; student.grade = 22; //将数据归档到path文件路径里面 BOOL success = [NSKeyedArchiver archiveRootObject:student toFile:path]; if (success) { NSLog(@"归档成功"); }else { NSLog(@"归档失败"); }
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; //完整的文件路径 NSString *path = [docPath stringByAppendingPathComponent:@"student.archiver"]; Student *student = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"student's name = %@, student's grade = %lu", student.name, student.grade);
//文件夹是否存在 BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:dir isDirectory:nil]; if (!fileExists) { NSLog(@"文件夹不存在"); NSError *error = nil; [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:&error]; if (error) { NSLog(@"error == %@", error.description); } else { NSLog(@"success"); } }
//查看是否有写入权限 if (![[NSFileManager defaultManager] isWritableFileAtPath:dir]) { NSLog(@"目录无写入权限"); }
文章参考文献:【iOS】数据持久化:使用NSKeyedArchiver进行数据归档svg