Шрифт:
передается сообщение 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).
Фреймворки для поддержки приложений, обеспечивающие удобный пользо-вательский интерфейс, называются Cocoa. Это два фреймворка: Foundation framework, с которым вы уже знакомы, и фреймворк Application Kit (или AppKit). Второй фреймворк содержит классы, связанные с окнами, кнопками, списками и т.д. 20.1. Уровни фреймворков
Чтобы показать уровни, которые отделяют приложение от оборудования, час-то используют схемы. Одна из таких схем показана на рис. 20.1.
Ядро системы обеспечивает низкоуровневую связь с оборудованием в форме драйверов устройств. Оно управляет ресурсами системы, такими как программы-планировщики, управление памятью и электропитанием и выполнение базовых операций ввода-вывода.
Сервисы ядра (Core Services) обеспечивают поддержку на нижнем уровне (уровне ядра), в отличие от находящихся выше уровней. Здесь обеспечивается поддержка коллекций, сетевого обмена, управления файлами, папок, управле-ния памятью, отладки, потоков, времени и электропитания.
Уровень Сервисов приложений (Application Services) включает поддержку печати и воспроизведения графики, включая Quartz, OpenGL и Quicktime. Пользователь
Рис. 20.1. Иерархия уровней для приложения