Процедуры RegisterClass и RegisterClasses удобнее и правильнее всего вызывать в initialization-секции .pas-модуля. Это даст нам уверенность в том, что до любого использования классов, объявленных в модуле, они будут зарегистрированы в потоковой системе.

Классы визуальных компонентов, зарегистрированных в IDE с помощью RegisterComponents, в вызове RegisterClass не нуждаются. Часть III. «Высший пилотаж» О псевдосвойствах

Есть одно существенное ограничение, относящееся ко всему сказанному выше. Рассмотренные случаи позволяют сериализовать только ту информацию, которая содержится в read/write published-свойствах класса. Однако всякому программисту известно, что информацию класса далеко не всегда допустимо выносить в такие свойства. Прежде всего, некоторые из свойств по архитектурному замыслу должны быть read-only, т. е. прямое присвоение их значений в программе не должно допускаться. Если мы вынесем read-only свойство в published-секцию, его значение сохранится в поток, но при десериализации не восстановится. С другой стороны, некоторые свойства вообще нельзя выносить за пределы protected-секции, а значения иных нуждающихся в сериализации полей должны быть только private.

И, кроме того, существует ещё один случай, для которого описанные выше приёмы сериализации бесполезны: если вместе с объектом должна сохраняться информация, представленная во вполне определённом формате – например, картинка или звук.

Здесь нас выручат псевдосвойства, которые предоставляют более общие механизмы сериализации, чем те, что доступны при использовании published-свойств, и дают фактически неограниченную свободу при создании систем, обладающих возможностью сохранять в потоке своё состояние. Определение псевдосвойств

Псевдосвойство – это то, что выглядит в dfm-формате как сериализованное published-свойство, но на самом деле таковым не является. Например, вот как выглядит сериализованная композиция TImage–TPicture, где объект типа TPicture доступен через свойство Picture:

object Image1: TImage . . . Picture.Data = { 0A544A504547496D616765. . . E0FF000BFFD9} end

Как и полагается, TPicture унаследован от TPersistent, однако не стоит искать Data среди его published-свойств.

Чтобы сделать информацию сериализуемой, не вынося её в published-свойства рассмотренных типов, можно воспользоваться псевдосвойствами, которые задаются в предназначенном для переопределения protected-методе класса TPersistent

procedure DefineProperties(Filer: TFiler); virtual;

Как и в случае с рассмотренным выше методом GetChildren, предполагается, что программист, переопределив данный метод, выполнит в нём заданные действия. А именно, для каждого будущего псевдосвойства вызовет у объекта Filer один из двух методов:

procedure DefineProperty(const Name: string; ReadData: TReaderProc; WriteData: TWriterProc; HasData: Boolean); virtual; abstract; procedure DefineBinaryProperty(const Name: string; ReadData, WriteData: TStreamProc; HasData: Boolean); virtual; abstract;

где

type TReaderProc = procedure(Reader: TReader) of object; TWriterProc = procedure(Writer: TWriter) of object; TStreamProc = procedure(Stream: TStream) of object;

Аргумент Name этих методов предназначен для передачи в него имени будущего псевдосвойства. Имена псевдосвойств должны быть корректными идентификаторами с точки зрения синтаксиса Pascal и не конфликтовать с именами других псевдо- и published-свойств – впрочем, эти требования, как ни странно, не категоричны. В ReadData и WriteData передаются ссылки на методы сериализуемого класса, отвечающие за чтение и запись информации псевдосвойства (ниже мы подробнее остановимся на этих методах). Аргумент HasData позволяет реализовать то, о чём говорилось выше в связи с ключевым словом default. Для того чтобы при определённых условиях псевдосвойство не сериализовалось, нужно сделать так, чтобы к моменту сериализации HasData получало False. В процессе же десериализации HasData никак не учитывается – если свойство будет найдено в потоке, оно будет прочитано, если нет – информация в объекте останется, как есть.

<<< 0 1 2 3 4 5 6 7 8 >>>
Хостинг от uCoz