Чтение онлайн

на главную - закладки

Жанры

Программирование на Objective-C 2.0
Шрифт:

Следующие два метода, которые используются для класса 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; }

Вывод программы 19.7 ======== Contents of: Steve’s Address Book == Jamie Baker jbaker@hitmail.com Julia Kochan jewls337@axlc.com Stephen Kochan steve@steve_kochan.com Tony lannino tony.iannino@techfitness.com

При разархивации этой адресной книги автоматически вызываются методы декодирования, добавленные в эти классы. Чтение в программу адресной книги выполняется предельно просто.

Метод encodeObjectforKey: используется применительно к встроенным классам и классам, для которых вы пишете свои методы кодирования и декодирования согласно протоколу NSCoding. Если ваши переменные экземпляра содержат некоторые базовые типы данных, например, int или float, вы должны знать, как кодировать и декодировать их (см. таблицу 19.1).

Ниже приводится простое определение для класса с именем Foo, который содержит три переменные экземпляра: типа NSString, типа int и типа float. Этот класс содержит один метод-установщик, три метода-получателя и два метода кодирования/декодирования, используемых для архивации. @interface Foo: NSObject <NSCoding> { NSString *strVal; int intVal; float floatVal; } @property (copy, nonatomic) NSString *strVal; @property int intVal; @property float floatVal; @end

Затем следует файл секции implementation. @implementation Foo @synthesize strVal, intVal, floatVal; -(void) encodeWithCoder: (NSCoder *) encoder { [encoder encodeObject: strVal forKey: @"FoostrVarj; [encoder encodelnt: intVal forKey: @"FoointVal"]; [encoder encodeFloat: floatVal forKey: @"Foofk>atVar]; } -(id) initWithCoder: (NSCoder *) decoder { strVal = [[decoder decodeObjectForKey: @"FoostrVal"] retain]; intVal = [decoder decodelntForKey: @"FoointVar]; floatVal = [decoder decodeFloatForKey: @'FoofloatVal"]; return self; } @end

В этой процедуре кодирования сначала кодируется строковое значение strVal с помощью метода encodeObject:forKey:, как показано ранее.

В программе 19.8 создается объект Foo, выполняется его архивация в файл, разархивация и последующий вывод. #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSAutoreleasePool.h> #import "Foo.h" // Definition for our Foo class int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Foo *myFoo1 = [[Foo alloc] init]; Foo *myFoo2; [myFool setStrVal: @»This is the string»]; [myFool setlntVal: 12345]; [myFool setFloatVal: 98.6]; [NSKeyedArchiver archiveRootObject: myFool toFile: @"foo.arch"]; myFoo2 = [NSKeyedUnarchiver unarchiveObjectWithFile: @"foo.arch"]; NSLog (@"%@\n%i\n%g", [myFoo2 strVal], [myFoo2 intVal], [myFoo2 floatVal]); [myFool release]; [pool drain]; return 0; }

Вывод программы 19.8 This is the string (Это строка) 12345 98.6

Архивация трех пробных экземпляра из объекта выполняется с помощью следующих сообщений. [encoder encodeObject: strVal forKey: @"FoostrVar]; [encoder encodelnt: intVal forKey: @"FoointVal“]; [encoder encodeRoat: floatVal forKey: @"FoofloatVa!''];

Некоторые из базовых типов данных, такие как char, short, long и long long, не включены в таблицу 19.1; для них необходимо определить размер объекта дан-ных и использовать соответствующую процедуру. Например, тип short int обыч-но имеет размер 16 битов, int и long — 32 или 64 бита, и long long — 64 бита. (Размер любого типа данных определяется с помощью оператора sizeof, см. главу 13.) Например, данные типа short int нужно сохранить их сначала как тип int и затем архивировать с помощью encodeintforKey:. Для декодирования нужно использовать обратный процесс: применить decodelnt:forKey: и затем присвоить результат переменной типа short int. 19.4. Использование NSData для создания нестандартных архивов

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

Адепт

Листратов Валерий
4. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Адепт

За Горизонтом

Вайс Александр
8. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
За Горизонтом

Звездная Кровь. Экзарх III

Рокотов Алексей
3. Экзарх
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Экзарх III

Неудержимый. Книга XXVI

Боярский Андрей
26. Неудержимый
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXVI

Я все еще не царь. Книга XXVI

Дрейк Сириус
26. Дорогой барон!
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Я все еще не царь. Книга XXVI

Лекарь Империи 9

Карелин Сергей Витальевич
9. Лекарь Империи
Фантастика:
городское фэнтези
аниме
боевая фантастика
5.00
рейтинг книги
Лекарь Империи 9

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14

Морской волк. 1-я Трилогия

Савин Владислав
1. Морской волк
Фантастика:
альтернативная история
8.71
рейтинг книги
Морской волк. 1-я Трилогия

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Черный Маг Императора 12

Герда Александр
12. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 12

Афганский рубеж 3

Дорин Михаил
3. Рубеж
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Афганский рубеж 3

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Второгодка. Книга 5. Презренный металл

Ромов Дмитрий
5. Второгодка
Фантастика:
городское фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Второгодка. Книга 5. Презренный металл

Последний Герой. Том 3

Дамиров Рафаэль
3. Последний герой
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Последний Герой. Том 3