Подтвердить что ты не робот

Objective-C Отражение для универсальной реализации NSCoding

Есть ли какие-либо средства отражения в Objective-C, которые позволят вам писать общие реализации NSCoding, проверяя общедоступные свойства объекта и генерируя общие реализации encodeWithCoder: и initWithCoder:.

Я думаю о чем-то вроде XStream для Java, который позволяет использовать общий способ сериализации и десериализации объектов Java с использованием отражения. Еще лучше, вероятно, было бы некоторым средством маркировки свойств как объектов, которые вы хотите сериализовать или которые являются временными (например, ключевое слово transient в Java).

Я читал документацию Руководство по программированию и сериализации архивов для Cocoa. Я понимаю, что вам нужен некоторый контроль над сериализацией ваших объектов, но это, как правило, симметричный процесс, и кажется странным, что нужно отменить то, что закодировано для сериализации, чтобы десериализовать его. Я сторонник СУХОЙ (не повторяйся).

4b9b3361

Ответ 1

Не только это возможно, но у меня есть друг, который сделал удар, делая именно это. (Вы можете увидеть его блог об этом здесь.) Отражение выполняется с использованием функций выполнения Objective-C, задокументированных в Objective-C 2.0 Runtime Reference. Посмотрите.

Обратите внимание, однако, что это будет работать только в том случае, если вы хотите, чтобы общее поведение сохраняло все переменные экземпляра. Вы, возможно, не захотите, чтобы NSView сохранил свой супервизор; в таких случаях общий случай не будет работать.

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

Ответ 2

(Я являюсь автором сообщения в блоге, связанным с комментарием BJ Homer). Есть пара предостережений для использования кода:

  • Целевой класс должен соответствовать требованиям KVC. Если вы используете Objective-C 2.0 свойства для ваших ivars, тогда вы все настроены. В противном случае вам нужно убедиться, что ваш класс настроен на правильный ответ на valueForKey: и setValue: forKey: methods.
  • В коде используется недокументированная "функция" среды выполнения, чтобы рекурсивно согласовать классы ivar с NSCoding. При компиляции почти вся информация о наборе текста (AFAIK) удаляется из кода, но для сохранения ivars они также должны соответствовать NSCoding. Я обнаружил, что если ivar является объектом, и я вызываю ivar_getTypeEncoding() на нем, я получу строку c, которая выглядит примерно так: {#IVAR_CLASS} (Пример: {#NSString}). То, что я делаю, это получить строку между # и}, создать объект класса с помощью NSClassFromString и перезаписать его.
  • Этот код сохранит ВСЕ ИВАДЫ.
  • Используйте на свой страх и риск (конечно)

Я написал это в основном как доказательство концепции, и есть много случаев, когда этот код не удастся эффектно. Например, в объекте A есть ivar для B, а B имеет ivar для A, тогда использование кода для сериализации одного или другого будет (я считаю) причиной бесконечного цикла.

Тем не менее, я думаю, что довольно волнующе, что Objective-C даже позволяет вам делать вещи, как в первую очередь.

Ответ 3

Проверьте RMModelObject:

http://www.realmacforge.com/svn/trunk/RMModelObject/

Однако обратите внимание, что ObjC Runtime работает в 10.5 и в Simulator, но не на реальном iPhone. Обнаружено, что трудно. Может быть OS 3.0, наконец, поддерживает его, но я не проверял.