Вход/Регистрация
Программирование на Objective-C 2.0
вернуться

Кочан Стивен

Шрифт:

В общем случае метод кодирования должен указывать, как архивировать каждую переменную экземпляра в объекте, который нужно сохранить. Для этого есть вспомогательные средства. Для описанных выше базовых классов Objective- С можно использовать метод encodeObject:forKey:. Для базовых типов данных С (например, делых и с плавающей точкой) используется один из методов, при-веденных в таблице 19.1. Метод декодирования (decoder), initWithCoder:, действует в обратном порядке: мы используем decodeObject:forKey: для декодирования ба-зовых классов Objective-C и подходящий метод декодирования из таблицы 19.1 для базовых типов данных С

Таблица 19.1. Кодирование и декодирование базовых типов данных в архивах с ключами Метод кодирования Метод декодирования encodeBool:forKey: decodeBool:forKey: encodelnt:forKey: decodelnt:forKey: encodelnt32:forKey: decodelnt32:forKey: encodelnt64:forKey: decodelnt64:forKey: encodeFloat:forKey: decodeFloal:forKey: encodeDouble:forKey: decodeDouble:forKey:

В программе 19.5 в классы AddressCard и AddressBook добавлены методы кодирования и декодирования. #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/N$KeyedArchiver.h> @interface AddressCard: NSObject <NSCoding, NSCopying> { NSString *name; NSString *email; ) @property (copy, nonatomic) NSString *name, *email; -(void) setName: (NSString *) theName andEmail: (NSString *) theEmail; -(NSComparisonResult) compareNames: (id) element; -(void) print; // Дополнительные методы для протокола NSCopying -(AddressCard *) copyWithZone: (NSZone *) zone; -(void) retainName: (NSString *) theName andEmail: (NSString *) theEmail; @end

Следующие два метода, которые используются для класса AddressCard, должны быть добавлены в файл секции implementation. -(void) encodeWithCoder: (NSCoder *) encoder { [encoder encodeObject: name forKey: @"AddressCardName"]; [encoder encodeObject: email forKey: @"AddressCardEmair[; -(id) initWithCoder: (NSCoder *} decoder { name = [[decoder decodeObjectforKey: @"AddressCardName"] retain]; email = [[decoder decodeObjectforKey: @'AddressCardEmail"] retain]; return self; }

Метод кодирования encodeWithCoder: передается объекту NSCoder в качестве его аргумента. Поскольку класс AddressCard наследует непосредственно из NSObject, нам не нужно заботиться о кодировании наследуемых переменных экземпляра. Если суперкласс вашего класса согласуется с протоколом NSCoding, то, чтобы обеспечить кодирование своих наследуемых переменных экземпляра, вы должны начать метод кодирования со строки [super encodeWithCoder: encoder];

Наша адресная книга содержит две переменные экземпляра с именами name н email. Поскольку это объекты класса NSString, мы можем использовать метод encodeObject:forKey: для кодирования каждой из них по порядку. Затем эти переменные экземпляра добавляются в архив.

Метод encodeObject:forKcy: кодирует объект и сохраняет его с указанным ключом для последующего считывания с помощью этого ключа. Имена ключей можно задавать произвольно, для считывания (декодирования) данных нужно использовать тот же ключ, который использовался для их архивации (коди-рования). Конфликт может возникнуть только в том случае, если тот же ключ используется для подкласса кодируемого объекта. Чтобы не возникла эта ситуация, можно вставить имя класса перед именем переменной экземпляра, когда вы составляете ключ для архива, как это сделано в программе 19.5.

Отметим, что encodeObject:forKey: можно использовать для любого объекта, в классе которого имеется соответствующий реализованный метод encodeWithCoder:.

Процесс декодирования действует в обратном порядке. Аргумент, переда-ваемый initWithCoder:, тоже являегся объектом NSCoder. Вам не нужно заботиться об этом ар|ументе; он получает сообщения для каждого объекта, который вы хотите извлечь из архива.

Поскольку в данном случае класс AddressCard наследует непосредственно из NSObject, вам не нужно заботиться о декодировании наследуемых переменных экземпляра. Достаточно вставить следующую строку в начало ваше метода декодирования (decoder), если ваш класс согласуется с протоколом NSCoding. self = [super initWithCoder: decoder];

Каждая переменная экземпляра затем декодируется путем вызова метода decodeObjectforKey: и передачи того же ключа, который использовался для кодирования этой переменной.

Аналогично классу AddressCard, мы добавляем методы кодирования и декодирования в класс AddressBook. В файле секции interface нужно только изменить строку с директивой @interface, чтобы объявить, что теперь с протоколом NSCoding согласуется класс AddressBook. Это изменение может выглядеть следующим образом. @interface AddressBook: NSObject <NSCoding, NSCopying>

Ниже определяются методы для включения в файл секции implementation. -(void) encodeWithCoder: (NSCoder *) encoder { (encoder encodeObject: bookName forKey: "AddressBookBookName"]; (encoder encodeObject: book forKey: @"AddressBookBook"]; } -(id) initWithCoder: (NSCoder *} decoder { bookName = [[decoder decodeObjectForKey: @"AddressBookBookName"] retain]; book = [[decoder decodeObjectForKey: @"AddressBookBook"] retain]; return self; }

Программа 19.6 — это тестовая программа. #import «AddressBook. h» #import <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { NSString *aName = @"Julia Kochan"; NSString *aEmail = @"jewls337@axlc.com"; NSString *bName = @"Tony lannino"; NSString *bEmail = @"tony.iannino@techfitness.com"; NSString *cName = @"Stephen Kochan"; NSString *cEmail = @"steve@steve_kochan.com''; NSString *dName = @"Jamie Baker"; NSString *dErnail = @"jbaker@hitmail.com"; NSAutoreteasePool * pool = [[NSAutoreleasePool alloc] init]; AddressCard *card1 = [[AddressCard alloc] ini:]; AddressCard *card2 = [[AddressCard alloc] init]; AddressCard *card3 = [[AddressCard alloc] initj; AddressCard *card4 = [[AddressCard alloc] init); AddressBook *myBook = [AddressBook alloc]; // Сначала задаем четыре адресные карточки [card 1 setName: aName andEmail: aEmail]; [card2 setName: bName andEmail: bEmail]; [card3 setName: cName andEmail: cEmail]; [card4 setName: dName andEmail: dEmail]; myBook = [myBook initWithName: (@"Steve's Address Book"]; // Добавляем несколько карточек в адресную книгу [myBook addCard: card 1 ]; [myBook addCard: card2]; [myBook addCard: card3]; [myBook addCard: card4]; [myBook sort]; if ([NSKeyedArchiver archiveRootObject: myBook toFile: @"addrbook.arch"] == NO) NSLog ((@"archiving failed"); [card 1 release]; [card2 release]; [card3 release]; [card4 release]; [myBook release]; [pool drain]; return 0; }

Эта программа создает адресную книгу и затем архивирует ее в файле addrbook.arch. При создании архивного файла метод кодирования вызываются из обоих классов: AddressBook и AddressCard. Если вы хотите проверить это, добавьте в методы несколько вызовов NSLog.

В программе 19.7 показано, как считывать архив в память для создания ад-ресной книги из файла. #import "AddressBook.h" #import <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { AddressBook *myBook; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; myBook = [NSKeyedUnarchiver unarchiveObjectWithFile: (@"addrbook.arch"]; [myBook list]; [pool drain]; return 0; }

  • Читать дальше
  • 1
  • ...
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: