Delphi 3. Библиотека программиста

       

Потоки и TPersistent


«Устойчивостью» (persistence) называется способность объекта продолжать свое существование в течение некоторого времени. В Delphi имя TPersistent было присвоено классу, специально разработанному так, чтобы его объекты сохранялись при нескольких запусках программы. Чтобы объект мог пережить завершение программы, важнейшая информация о нем записывается в поток и загружается позднее.

Потоки Delphi умеют работать с классом TPersistent, так что чтение и запись объектов происходит почти автоматически. Однако не все объекты TPersistent равноценны. Компоненты , являющиеся потомками TPersistent, можно сохранять и загружать удобными методами TStream.WriteComponent и ReadComponent. Но другие потомки TPersistent сохраняются в потоках лишь в том случае, если они представляют собой published-свойства компонентов — то есть теряют самостоятельность.

Это становится неудобным, если мы захотим сохранить в потоке, например, шрифтовой объект. Сначала придется объявить новый тип компонента с published-свойством TFont, затем создать экземпляр этого компонента, присвоить шрифтовому свойству наш объект и записать компонент в поток.

Но если все, что вам нужно — это «рабочая лошадка», которая возит на себе TPersistent, необязательно каждый раз объявлять новый класс. Необходим всего один класс для компонента с published-свойством TPersistent; полиморфизм позволяет назначить этому свойству объект любого класса-потомка TPersistent, и он будет сохраняться и загружаться вместе с компонентом.

Компонент TCarrier (см. листинг 9.17) как раз и является таким «вьючным животным». Он спрятан в секции implementation модуля StrmPers, а процедуры WritePersistent и ReadPersistent занимаются созданием, использованием и уничтожением временных экземпляров его объектов. Не забудьте создать свой TPersistent перед тем, как использовать его при вызове ReadPersistent; к этому моменту объект уже должен существовать.

Листинг 9.17. Модуль STRMPERS.PAS

unit StrmPers; interface uses Classes; procedure WritePersistent( Stream: TStream; Persistent: TPersistent ); { ЗАМЕЧАНИЕ: Объект TPersistent должен быть создан до его передачи этой процедуре... } procedure ReadPersistent( Stream: TStream; Persistent: TPersistent ); implementation type TCarrier = class( TComponent ) private FPersistent: TPersistent; published property Persistent: TPersistent read FPersistent write FPersistent; end; procedure WritePersistent( Stream: TStream; Persistent: TPersistent ); var Carrier: TCarrier; begin Carrier := TCarrier.Create( nil ); try Carrier.Persistent := Persistent; Stream.WriteComponent( Carrier ); finally Carrier.Free; end; end; procedure ReadPersistent( Stream: TStream; Persistent: TPersistent ); var Carrier: TCarrier; begin Carrier := TCarrier.Create( nil ); try Carrier.Persistent := Persistent; Stream.ReadComponent( Carrier ); finally Carrier.Free; end; end; end.

Содержание раздела