• (void)encodeWithCoder:(NSCoder *)aCoder — от этого метода мы получаем сущность-кодировщик. Кодировщик используется точно так же, как словарь. Просто храните в нем значения с ключами на ваш выбор;
• (instancetype)initWithCoder:(NSCoder *)aDecoder; — этот метод вызывается в вашем классе всякий раз, когда вы пытаетесь разархивировать класс с помощью NSKeyedUnarchiver. Просто считывайте значения их экземпляра NSCoder, передаваемого этому методу.
Итак, учитывая сказанное, реализуем наш класс:
#import «Person.h»
NSString *const kFirstNameKey = @"FirstNameKey";
NSString *const kLastNameKey = @"LastNameKey";
@implementation Person
— (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject: self.firstName forKey: kFirstNameKey];
[aCoder encodeObject: self.lastName forKey: kLastNameKey];
}
— (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self!= nil){
_firstName = [aDecoder decodeObjectForKey: kFirstNameKey];
_lastName = [aDecoder decodeObjectForKey: kLastNameKey];
}
return self;
}
@end
Как видите, мы работаем с экземпляром класса NSCoder практически так же, как и со словарем. Разница заключается в том, что вместо словарного метода setValue: forKey: мы пользуемся encodeObject: forKey:, а вместо словарного метода objectForKey: задействуем decodeObjectForKey:. Отличия от словарей минимальны.
Итак, с этим классом все понятно. Теперь реализуем механизм архивации и деархивации, пользуясь двумя вышеупомянутыми классами. Мы собираемся сначала инстанцировать объект типа Person, затем заархивировать его, убрать из памяти, потом считать обратно из файла и убедиться, что разархивированное значение совпадает с тем, которое мы изначально записали в класс. Все это мы реализуем в делегате приложения, поскольку там это будет сделать проще всего:
#import «AppDelegate.h»
#import «Person.h»
@implementation AppDelegate
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
/* Определяем имя и фамилию, которые собираемся задать в объекте */
NSString *const kFirstName = @"Steven";
NSString *const kLastName = @"Jobs";
/* Определяем, где хотим заархивировать объект */
NSString *filePath = [NSTemporaryDirectory()
stringByAppendingPathComponent:@"steveJobs.txt"];
/* Инстанцируем объект */
Person *steveJobs = [[Person alloc] init];
steveJobs.firstName = kFirstName;
steveJobs.lastName = kLastName;
/* Архивируем объект в файл */
[NSKeyedArchiver archiveRootObject: steveJobs toFile: filePath];
/* Теперь разархивируем этот же класс в другой объект */
Person *cloneOfSteveJobs =
[NSKeyedUnarchiver unarchiveObjectWithFile: filePath];
/* Проверяем, совпадают ли имя и фамилия в разархивированном объекте
с именем и фамилией, которые находились в ранее архивированном объекте */
if ([cloneOfSteveJobs.firstName isEqualToString: kFirstName] &&
[cloneOfSteveJobs.lastName isEqualToString: kLastName]){
NSLog(@"Unarchiving worked");
} else {
NSLog(@"Could not read the same values back. Oh no!");
}
/* Временный файл нам больше не нужен, удаляем его */
NSFileManager *fileManager = [[NSFileManager alloc] init];
[fileManager removeItemAtPath: filePath error: nil];