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

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

Жанры

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

Возможно, вы не хотите записывать объект непосредственно в файл с помощью метода archiveRootObject:ToFile:, как в предыдущих примерах. Например, вам нужно собрать некоторые объекты и сохранить их в одном архивном файле. Это можно сделать с помощью обобщенного класса объектов потока данных (data stream) NSData.

Как говорилось в главе 16, объект класса NSData можно использовать для ре-зервирования области памяти для сохранения данных. Эту область памяти можно использовать, например, для временного хранения данных, которые будут последовательно записываться в файл, или для хранения содержимого файла, считанного с диска. Проще всего создать мутабельную область данных с помощью метода data. dataArea = [NSMutableData data];

В результате создается пустое буферное пространство, размер которого расширяется по мере выполнения программы.

В качестве простого примера предположим, что нужно архивировать в од-ном файле адресную книгу и один из объектов класса Foo. Предположим также, что мы добавили методы архивации с ключами в классы AddressBook и AddressCard (см. программу 19.9). #import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSString.h> #import < Foundation/NSKeyedArchiver. h> #import <Foundation/NSCoder.h> #import <Foundation/NSData.h> #import "AddressBook.h" #import Too.h" int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Foo *myFoo1 = [[Foo alloc] init]; Foo *myFoo2; NSMutableData *dataArea; NSKeyedArchiver *archiver; AddressBook *myBook; // Вставьте здесь код из программы 19.7 для создания в myBook // адресной книги, содержащей четыре адресные карточки [myFool setStrVal: @"This is the string"]; [myFool setlntVal: 12345]; [myFool setFloatVal: 98.6]; // Создание области данных и ее присоединение к объекту NSKeyedArchiver dataArea = [NSMutableData data]; archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: dataArea]; // Теперь можно начать архивацию объектов [archiver encodeObject: myBook forKey: @"myaddrbook"]; [archiver encodeObject: myFool forKey: @"myfoor]; [archiver finishEncoding]; // Запись архивируемой области данных в файл if ([dataArea writeToFile: @"myArchive" atomically: YES encoding: NSUTF8Encoding error: nil] == NC) NSLog (@"Archiving failed!"); (Архивация на выполнена) [archiver release]; [myFool release]; [pool drain]; return 0; }

После выделения памяти для объекта NSKeyedArchiver передается сообщение initForWritingWithMutableData:, чтобы указать область, в которую будут записываться архивируемые данные; это область NSMutabledata с именем dataArea, которая была создана выше. Сохраненному в архиваторе объекту NSKeyedArchiver можно передавать теперь сообщения кодирования для архивации объектов в программе. На самом деле, архивация и сохранение все кодируемых сообщений выполняется в указанной области данных, пока не получено сообщение finishEncoding.

В данном случае кодируются два объекта: наша адресная книга и объект класса Foo. Для этих объектов можно использовать encodeObjectiforKey:, поскольку мы ранее реализовали методы кодирования (encoder) и кодирования (decoder) для классов AddressBook, AddressCard и Foo.

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

Область с именем dataArea теперь содержит наши архивированные объекты в форме, которую можно записать в файл. В выражении с сообщением [dataArea writeToFile: @"myArchive" atomically: YES encoding: NSUTF8Encoding error: nil]

передается сообщение writeToFtle:atomically:encoding:error: потоку данных для записи его данных в указанный файл с именем myArchive.

Как видно из части с оператором if, метод writeToFi(e:atomicalfy:encoding:error: возвращает значение YES типа BOOL, если операция записи успешно выполнена, и значение N0, если ее не удалось выполнить (например, был указан неверный путь к файлу или переполнена файловая система).

Восстановление данных из архивного файла осуществляется просто: нужно выполнить все действия в обратном порядке. Во-первых, нужно выделить, как и раньше, область данных, затем в эту область данных прочитать архивный файл. После этого мы создаем объект NSKeyedUnarchiver и сообщаем ему, что требуется декодировать данные из указанной области. Для извлечения и декодирования архивированных объектов нужно вызвать методы декодирования, а по окончании - передать сообщение finishDecoding объекту NSKeyedUnarchiver. Все это выполняется в программе 19. К). #import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSString.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSCoder.h> #import <Foundation/NSData.h> #import "AddressBook.h" #import "Foo.h" * pool = [[NSAutoreleasePool alloc] inrt]; *dataArea; *unarchiver; *myFoo1; *myBook; // Чтение архива и присоединение к нему // объекта NSKeyedUnarchiver dataArea = [NSData dataWithContentsOfFile: @"myArchive"]; if (! dataArea) { NSLog (@"Can’t read back archive file!"); Return (1); } unarchiver = [[NSKeyedllnarchiver alloc] initForReadingWithData: dataArea]; // Декодирования объектов, которые мы сохранили ранее в этом архиве myBook = [unarchiver decodeObjectForKey: @nmyaddrbook"]; myFool = [unarchiver decodeObjectForKey: @"myfoo1"]; [unarchiver finishDecoding]; [unarchiver release]; // Проверка того, что восстановление успешно выполнено [myBook list]; NSLog ("%@\n%i\n%g", [myFool strVal], [myFool intVal], [myFool floatVal]); [pool release]; return 0; }

Вывод программы 19.10 ======== 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 This is the string 12345 98.6

Адресная книга и объект Foo были успешно восстановлены из архивного файла. 19.5. Использование архиватора для копирования объектов

В программе 18.2 мы пытались создать копию массива, содержащего мутабель- ные строковые элементы, и создали поверхностную (shallow) копию этого мас-сива — копировались не сами строки, а только ссылки на них.

Возможности архивации Foundation позволяют создать глубокую (deep) ко-пию объекта. Например, в программе 19.11 выполняется копирование dataAnay в dataArray2 путем архивации dataAnay в буфер и его последующей деархивании с присваиванием результата массиву dataArray2. Нам не нужно задействовать файл для этого процесса; архивацию и деархивацию можно выполнять в памяти. #import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool. h> #import <Foundation/NSString.h> #import <Foundation/NSKeyedArchiver.h> #import <Foundation/NSArray.h> int main (int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSData *data; NSMutableArray *dataArray = [NSMutableArray arrayWithObjects: [NSMutableString stringWithString; @"one"], [NSMutableString stringWithString; @"two"], [NSMutableString stringWithString: @ "three"], nil ]; NSMutableArray *dataArray2; NSMutableString *mStr; // Создание глубокой копии с помощью архиватора data = [NSKeyedArchiver archivedDataWithRootObject: dataArray]; dataArray2 = [NSKeyedUnarchiver unarchiveObjectWithData: data]; mStr = [dataArray2 objectAtlndex: 0]; [mStr appendString: @"ONE"]; NSLog (@"'dataArray:"); for ( NSString *elem in dataArray ) NSLog (n%@", elem); NSLog (@"\ndataArray2: "); for ( NSString *elem in dataArray2 ) NSLog ("%@"\ elem); [pool drsin]; return 0; }

Вывод программы 19.11 dataArray: one two three dataArray2: oneONE two three

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

Операция копирования в программе 19.11 выполняется с помощью следующих двух строк. data - [NSKcycdArchiver archivedDataWithRootObject: dataArray]; dataArray2 = [NSKeyedUnarchiver unarchiveObjectWithData: data];

Мы можем избежать промежуточного присваивания и выполнить копиро-вание с помощью одного оператора. dataArray2 = [NSKeyedUnarchiver unarchiveObjectWithData; [NSKeyedArchiver archivedDataWithRootObject: dataArray]];

Этот подход полезен для создания глубокой копии объекта или объекта, который не поддерживает протокол NSCopying. Упражнения

В главе 15 в программе 15.7 была создана таблица простых чисел. Внесите изменения в эту программу, чтобы записать результирующий массив в виде списка свойств ХМ L в файл primes.pl. Проверьте содержимое этого файла.

Напишите программу для чтения списка свойств XML, созданного в упражнении 1, и сохраните эти свойства в объекте-массиве. Выполните вывод всех элементов массива, чтобы убедиться, что операция восстановления прошла успешно.

Внесите изменения в программу 19.2, чтобы вывести содержимое одного из списков свойств XML (файлы .plist), сохраненного в папке /Library/Preferences.

Напишите программу чтения архивированной адресной книги (AddressBook) и выполните поиск записи в соответствии с именем, указанным в командной строке, например $ lookup gregory

Часть III. Cocoa и SDK iPhone Глава 20. Введение в Cocoa

На протяжении этой книги мы разрабатывали программы, которые имеют до-вольно простой пользовательский интерфейс. Для вывода сообщений на кон-соль мы использовали процедуру @@ NSLog. Это действительно полезная про-цедура, но ее возможности ограничены. Другие программы, которые мы используем на своих Маках, имеют намного более удобный интерфейс. Репу-тация компьютеров Macintosh во многом основывается на дружественных пользовательских окнах и простоте использования. В своих приложениях мы можем использовать XCode вместе с приложением Interface Builder. Это сочета-ние образует мощную среду для разработки программ со средствами редакти-рования и отладки и удобным доступом к online-документации и позволяет легко разрабатывать сложные графические пользовательские интерфейсы (GUI).

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

Приказано выжить!

Малыгин Владимир
1. Другая Русь
Фантастика:
боевая фантастика
попаданцы
альтернативная история
7.09
рейтинг книги
Приказано выжить!

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

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

Курсант: назад в СССР 2

Дамиров Рафаэль
2. Курсант
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Курсант: назад в СССР 2

Неофит

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

Симфония теней

Злобин Михаил
3. Хроники геноцида
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Симфония теней

Лихие. Смотрящий

Вязовский Алексей
2. Бригадир
Фантастика:
попаданцы
5.00
рейтинг книги
Лихие. Смотрящий

Поход

Валериев Игорь
4. Ермак
Фантастика:
боевая фантастика
альтернативная история
6.25
рейтинг книги
Поход

Шайтан Иван 4

Тен Эдуард
4. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
8.00
рейтинг книги
Шайтан Иван 4

Герцог. Книга 1. Формула геноцида

Юллем Евгений
1. Псевдоним "Испанец" - 2
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Герцог. Книга 1. Формула геноцида

Наследие Маозари 2

Панежин Евгений
2. Наследие Маозари
Фантастика:
попаданцы
рпг
аниме
5.00
рейтинг книги
Наследие Маозари 2

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

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

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

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

Как я строил магическую империю 5

Зубов Константин
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5

Погранец

Поселягин Владимир Геннадьевич
2. Решала
Фантастика:
фэнтези
боевая фантастика
альтернативная история
5.00
рейтинг книги
Погранец