Objective-C Отражение для универсальной реализации NSCoding
Есть ли какие-либо средства отражения в Objective-C, которые позволят вам писать общие реализации NSCoding, проверяя общедоступные свойства объекта и генерируя общие реализации encodeWithCoder: и initWithCoder:.
Я думаю о чем-то вроде XStream для Java, который позволяет использовать общий способ сериализации и десериализации объектов Java с использованием отражения. Еще лучше, вероятно, было бы некоторым средством маркировки свойств как объектов, которые вы хотите сериализовать или которые являются временными (например, ключевое слово transient в Java).
Я читал документацию Руководство по программированию и сериализации архивов для Cocoa. Я понимаю, что вам нужен некоторый контроль над сериализацией ваших объектов, но это, как правило, симметричный процесс, и кажется странным, что нужно отменить то, что закодировано для сериализации, чтобы десериализовать его. Я сторонник СУХОЙ (не повторяйся).
Ответы
Ответ 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, наконец, поддерживает его, но я не проверял.