你的位置:首页 > 操作系统

[操作系统]iOS 对模型对象进行归档


归档是指一种形式的序列化,专门编写用于保存数据的任何对象都应该支持归档。使用对模型对象进行归档的技术可以轻松将复杂的对象写入文件,然后再从中读取它们。

只要在类中实现的每个属性都是标量或者都是遵循NSCoding协议的某个类的实例,你就可以对整个对象进行完全归档。大多数的Foundation和Cocoa Touch类 都遵NSCoding协议,所以对于有大多数类来说,归档不太难。

 

遵循NSCoding协议:

NSCoding声明了两个方法,

- (void)encodeWithCoder:(NSCoder *)aCoder;和- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

第一个是 将对象编码到归档中,第二个则是对归档解码,来创建一个对象。

在BIDFourLines中:

#import <Foundation/Foundation.h>@interface BIDFourLines : NSObject <NSCoding, NSCopying>@property (copy, nonatomic) NSArray *lines;@end

 

#import "BIDFourLines.h"static NSString * const kLinesKey = @"kLinesKey";@implementation BIDFourLines #pragma mark - Coding- (id)initWithCoder:(NSCoder *)aDecoder{  self = [super init];  if (self) {    self.lines = [aDecoder decodeObjectForKey:kLinesKey];  }  return self;}- (void)encodeWithCoder:(NSCoder *)aCoder;{  [aCoder encodeObject:self.lines forKey:kLinesKey];}#pragma mark - Copying- (id)copyWithZone:(NSZone *)zone;{  BIDFourLines *copy = [[[self class] allocWithZone:zone] init];  NSMutableArray *linesCopy = [NSMutableArray array];  for (id line in self.lines) {    [linesCopy addObject:[line copyWithZone:zone]];  }  copy.lines = linesCopy;  return copy;}@end

注:上面遵循了NSCopying协议,遵循NSCopying协议对于任何模型对象来说都是非常好的事情,NSCopying协议中,有一个copyWithZone方法,可以用来复制对象。

 

在BIDViewController中:

#import "BIDViewController.h"#import "BIDFourLines.h"static NSString * const kRootKey = @"kRootKey";@interface BIDViewController ()@property (strong, nonatomic) IBOutletCollection(UITextField) NSArray *lineFields;@end@implementation BIDViewController- (NSString *)dataFilePath{  NSArray *paths = NSSearchPathForDirectoriesInDomains(                             NSDocumentDirectory, NSUserDomainMask, YES);  NSString *documentsDirectory = [paths objectAtIndex:0];  return [documentsDirectory stringByAppendingPathComponent:@"data.archive"];}- (void)viewDidLoad{  [super viewDidLoad];  // Do any additional setup after loading the view, typically from a nib.  NSString *filePath = [self dataFilePath];  //如果存在归档  if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {    NSData *data = [[NSMutableData alloc]            initWithContentsOfFile:filePath];    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]                     initForReadingWithData:data];    //解档    BIDFourLines *fourLines = [unarchiver decodeObjectForKey:kRootKey];        [unarchiver finishDecoding];        for (int i = 0; i < 4; i++) {      UITextField *theField = self.lineFields[i];      theField.text = fourLines.lines[i];    }  }    //后台通知  UIApplication *app = [UIApplication sharedApplication];  [[NSNotificationCenter defaultCenter]   addObserver:self   selector:@selector(applicationWillResignActive:)   name:UIApplicationWillResignActiveNotification   object:app];}//进入后台时 归档- (void)applicationWillResignActive:(NSNotification *)notification{  NSString *filePath = [self dataFilePath];  BIDFourLines *fourLines = [[BIDFourLines alloc] init];  fourLines.lines = [self.lineFields valueForKey:@"text"];  NSMutableData *data = [[NSMutableData alloc] init];  NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]                 initForWritingWithMutableData:data];  [archiver encodeObject:fourLines forKey:kRootKey];  [archiver finishEncoding];  [data writeToFile:filePath atomically:YES];}