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

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

Жанры

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

Вывод программы 19.2 archiving: Storing an object for later use (архивация: сохранение объекта для дальнейшего использования) abstract class: A class defined so other classes can inherit from it (абстрактный класс: Класс, определенный таким образом, чтобы другие классы могли наследовать из него) adopt: То implement all the methods defined in a protocol (принять: для реализации всех методов, определенных в протоколе)

Ваши списки свойств не обязательно должны создаваться из программы на Objective-C; список свойств может поступать из любою источника. Вы можете создавать свои собственные списки свойств с помощью простою текстового ре-дактора или программы Property List Editor (Редактор списков свойств), которая находится в /Developer/Applications/Utilities на компьютерах с системой Mac OS X. 19.2. Архивация с помощью NSKeyedArchiver

В файле можно сохранять объекты любого типа, а не только строки, массивы и словари. Для этого необходимо создать архив с ключами (keyed archive) с помо-щью класса NSKeyedArchiver.

Mac OX X поддерживает архивы с ключами, начиная с версии I0.2. В ранних версиях с помощью класса NSArchiver создавались последовательные архивы (sequential archives). Данные последовательных архивов должны считываться точно в том же порядке, в каком они записывались.

В архиве с ключами каждое поле архива имеет имя. При архивации объекта мы присваиваем ему имя, или ключ. При считывании объекта из архива мы ис-пользуем тот же ключ. Это позволяет записывать объекты в архив и считывать их в любом порядке. Кроме того, есл и в классе добавляются или удаляются новые переменные экземпляра, это можно предусмотреть в программе.

Отметим, что NSArchiver недоступен в iPhone SDK. Если нужна архивация в iPhone, вы должны использовать NSKeyedArchiver.

Чтобы использовать архивы с ключами, нужно импортировать <Foundation/NSKeyedArchiver.h>.

В программе 19.3 показано, как сохранять файл на диске с помощью метода archiveRootObjectrtoRle: из класса NSKeyedArchiver. Чтобы использовать этот класс, нужно включить в программу соответствующий файл с помощью оператора #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/NSDictionary.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] initj; NSDictionary *glossary = [NSDictionary dictionaryWithObjectsAndKeys: @"A class defined so other classes can inherit from it", @"abstract class", @“To implement all the methods defined in a protocol", @"adopt", @"Storing an object for later use", @"archiving", nil ]; [NSKeyedArchiver archiveRootObject: glossary toFile: @"glossary.archive"]; [pool release]; return 0; }

Программа 19.3 не выводит никаких данных на терминал. Однако оператор [NSKeyedArchiver archiveRootObject: glossary toFile: @"glossary.archive"];

записывает словарь glossary в файл glossary.archive. Для этого файла можно задать любой путь. В данном случае файл записывается в текущую папку.

Этот архивный файл можно в дальнейшем читать в программу с помощью метода NSKeyedUnarchiver unArchiveObjectWithFile:, как показано в программе 19.4. #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/NSDictionary.h> #import <Foundation/NSEnumerator.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSAutoreleasePool.ti> int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] in it]; NSDictionary *glossary; glossary = [NSKeyedUnarchiver unarchiveObjectWithFile: @"glossary.archive"]; for ( NSString *key in glossary) NSLog (@"%@: %@", key, [glossary objectForKey: key]); [pool drain]; return 0; }

Вывод программы 19.4 abstract class: A class defined so other classes can inherit from it. adopt: To implement all the methods defined in a protocol archiving: Storing an object for later use.

Оператор glossary = [NSKeyedUnarchiver unarchiveObjectWithFile: @"glossary.archive"];

вызывает открытие указанного файла и считывание его содержимого. Файл должен быть создан в результате архивации, для него можно указывать полное или относительное имя, как в данном примере.

После восстановления словаря программа просто выполняет перебор его содержимого, чтобы убедиться, что восстановление было успешным. 19.3. Написание методов кодирования и декодирования

Объекты базовых классов Objective-C, таких как NSString, NSArray, NSDictionary, NSSet, NSDate, NSNumber и NSData, можно архивировать и восстанавливать, как описано в предыдущем разделе. Это относится и к объектам с вложенностью, например, массивам, содержащим строки или другие объекты-массивы.

Мы не можем непосредственно архивировать нашу адресную книгу (AddressBook) с помощью этих средств, поскольку система Objective-C «не знает», как архивировать объект класса AddressBook. Если попытаться архивировать его и программе с помощью строки [N S Keyed Arc h iver archiveRootObject: myAddressBook toFile: @naddrbook.arch"];

то при выполнении программы будет выведено сообщение *** -[AddressBook encodeWithCoder:]: selector not recognized (селектор не распознан) *** Uncaught exception: <NSInvalidArgumentException> (Невыявленное исключение) ***-[AddressBook encodeWithCoder:]: selector not recognized archiveTest: received signal: Trace/BPT trap

Из этих сообщений об ошибках мы видим, что система пыталась найти метод с именем encodeWithCoder: в классе AddressBook, но мы нигде не определяли такой метод.

Чтобы архивировать объекты, отличные от списка в начале раздела, мы должны указать системе, как эти объекты архивировать, или кодировать (encode), а также как их разархивировать, или декодировать (decode). Для этого нужно добавить в определения класса методы encodeWithCoder: и initWithCoder: согласно протоколу . В примере с адресной книгой нужно добавить эти методы в два класса: AddressBook и AddressCard.

Метод encodeWithCoder: вызывается каждый раз, когда архиватору нужно ко-дировать объект из указанного класса, и этот метод указывает ему, как это сделать. Аналогичным образом, метод initWithCoder: вызывается каждый раз, когда нужно декодировать объект указанного класса.

В общем случае метод кодирования должен указывать, как архивировать каждую переменную экземпляра в объекте, который нужно сохранить. Для этого есть вспомогательные средства. Для описанных выше базовых классов 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

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

Бояръ-Аниме. Газлайтер. Том 30

Володин Григорий Григорьевич
30. История Телепата
Фантастика:
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 30

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Войны Наследников

Тарс Элиан
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников

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

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

Помещик

Беличенко Константин
1. Помещик
Фантастика:
боевая фантастика
попаданцы
5.56
рейтинг книги
Помещик

Звездная Кровь. Изгой V

Елисеев Алексей Станиславович
5. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
технофэнтези
рпг
фантастика: прочее
5.00
рейтинг книги
Звездная Кровь. Изгой V

Кодекс Охотника XXXI

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

Сильнейший Столп Империи. Книга 2

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

Архил...? 4

Кожевников Павел
4. Архил...?
Фантастика:
фэнтези
попаданцы
альтернативная история
5.50
рейтинг книги
Архил...? 4

Древесный маг Орловского княжества

Павлов Игорь Васильевич
1. Орловское княжество
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Московское золото и нежная попа комсомолки. Часть Пятая

Хренов Алексей
5. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото и нежная попа комсомолки. Часть Пятая

Третий Генерал: Том IV

Зот Бакалавр
3. Третий Генерал
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Третий Генерал: Том IV

Контртеррор

Валериев Игорь
6. Ермак
Фантастика:
альтернативная история
5.00
рейтинг книги
Контртеррор