Кодирование и декодирование типов данных C
NSKeyedArchiver
и NSKeyedUnarchiver
обеспечьте много методов для обработки неданных объектов. Целые числа могут быть закодированы с encodeInt:forKey:
, encodeInt32:forKey:
, или encodeInt64:forKey:
. Аналогично, действительные значения могут быть закодированы с encodeFloat:forKey:
или encodeDouble:forKey:
. Другие методы кодируют булевские переменные и массивы байтов. Классы также обеспечивают несколько удобных методов для обработки специальных типов данных, используемых в Какао, такой как NSPoint
, NSSize
, и NSRect
.
NSKeyedArchiver
и NSKeyedUnarchiver
не обеспечивайте методы для кодирования и декодирования составных типов, таких как структуры, массивы и битовые поля. Следующие разделы обеспечивают предложения о том, как обработать неподдерживаемые типы данных.
Указатели
Вы не можете закодировать указатель и возвратить что-то полезное во время декодирования. Необходимо закодировать информацию, на которую указывает указатель. Это - истина в невключенном кодировании также.
Указатели на струны до (char *
) особый случай, потому что они могут быть обработаны как массив байтов, который может быть закодирован с помощью encodeBytes:length:forKey:
. Можно также обернуть струны до с временным файлом NSString
возразите и заархивируйте строку. Инвертируйте процесс при декодировании. Обязательно имейте в виду кодирование набора символов строки при создании NSString
объект, и выбрал надлежащий метод создания.
Массивы простых типов
При кодировании массива байтов можно просто использовать предоставленные методы, чтобы сделать так.
Для других арифметических типов создайте NSData
объект с массивом. Обратите внимание на то, что в этом случае контакт с проблемами порядка байтов платформы является Вашей ответственностью. Порядок байтов платформы может быть обработан двумя общими способами. Первый метод должен преобразовать элементы массива (или скорее временная копия массива) в канонический порядок байтов, или большой или мало, по одному с функциями, обсужденными в Свопинге Байтов в Универсальных Двоичных Инструкциях по Программированию, Второй Выпуск (см. также «Порядок байтов» в Ссылке Функций Основы), и дайте тот результат NSData
как буфер. (Или, можно записать байты непосредственно с encodeBytes:length:forKey:
.) Во время декодирования необходимо инвертировать процесс, преобразовывающий от канонической формы с прямым порядком байтов или с обратным порядком байтов до текущего представления узла. Другой метод должен использовать массив как есть и запись в отдельном включенном значении (возможно, булевская переменная), каким порядком байтов узел был, когда создавался архив. Во время декодирования считайте ключ порядка байтов и сравните его с порядком байтов текущего узла и подкачайте значения только если отличающийся.
Также можно заархивировать каждый элемент матрицы отдельно как их собственный тип, возможно при помощи ключевых имен, вдохновленных синтаксисом массива, как «theArray [0]», “theArray[1]”, и т.д. Это не ужасно эффективный метод, но можно проигнорировать проблемы порядка байтов.
Массивы объектов
Самая простая вещь сделать для массива C объектов состоит в том, чтобы временно обернуть массив в NSArray
объект с initWithObjects:count:
, закодируйте объект массива, затем избавьтесь от объекта. Поскольку объекты содержат другую информацию, которая должна быть закодирована, Вы не можете только встроить массив указателей в NSData
объект; каждый объект должен быть индивидуально заархивирован. Во время декодирования использовать getObjects:
на полученном массиве для возвращения объектов в выделенный массив C (корректного размера).
Структуры и битовые поля
Лучший метод для архивации структуры или набора битовых полей должен заархивировать поля независимо и выбрать надлежащий тип кодирования/декодирования метода для каждого. При необходимости как «theStruct.order», «theStruct.flags», и т.д., ключевые имена могут быть составлены из имен полей структуры. Это создает небольшую зависимость от имен полей в исходном коде, который в течение долгого времени может переименовываться, но ключи архивации не могут измениться, если Вы хотите поддержать совместимость.
Вы не должны обертывать структуру с NSData
объект и архив это. Если структура содержит объект или поля указателя, объект данных не собирается архивировать их правильно. Вы также создаете зависимость от того, как компилятор решает разметить структуру, которая может измениться между версиями компилятора и может зависеть от других факторов. Компилятор не ограничивается организовать структуру так же, как Вы указали его в исходном коде — могут быть произвольные внутренние и невидимые дополнительные байты между полями в структуре, например, и сумма их может измениться без предварительного уведомления и на различных платформах. Кроме того, любые поля, которые являются многократными байтами по ширине, не собираются обрабатываться правильно относительно проблем порядка байтов. Вы вызовете себя все виды проблемы совместимости.
Аналогично, битовые поля никогда не должны кодироваться путем чтения необработанных битов нескольких битовых полей как целое число и кодирования целого числа. (Кодирование целого числа, которое Вы создаете вручную из нескольких битовых полей, с помощью сдвигов разряда и операций OR, однако, избегает большинства следующих ловушек.) Несмотря на то, что существуют некоторые требования к компиляторам, указанным в стандарте C, компилятор все еще имеет некоторую свободу в том, как вещи фактически организованы и какие биты это принимает решение сохранить, где, и какие биты это может принять решение не использовать (межполевые дополнительные биты). Расположение тех битов могло отличаться между компиляторами или измениться, поскольку развивается определенный компилятор. Поверх этого также необходимо иметь дело с проблемами порядка байтов. Порядок битов в целом числе мог отличаться для машины, кодирующей архив и машину, декодирующую его. Наконец, путем кодирования необработанных битов, Вы ограничиваете будущую разработку своего класса использовать те же размеры битового поля в качестве самого старого архива, который необходимо поддерживать. Иначе, необходимо быть в состоянии проанализировать старый поток битов и инициализировать новый поток битов сами, обрабатывая компилятор, и платформа выходит соответственно.
Как имеет место для переменных экземпляра объекта в целом, не необходимо заархивировать каждое поле структуры или битового поля. Только необходимо закодировать и декодировать поля, требуемые сохранить состояние структуры. Поля, вычисленные или иначе полученные другими средними значениями, не должны быть заархивированы.
Более сложные типы данных
Более сложные типы данных, такие как массивы агрегатов, могут обычно обрабатываться с помощью методов для простых типов данных и комбинируя их с пользовательской логикой для определенного приложения.