Як зберегти список
Як зберегти список
Не можу ось згадати як зберегти список об'єктів компонента. Всі об'єкти спадкоємці TPersistent, але не одного типу - TCollection не підійде. Якщо хто вже робив, підкажіть як краще. Сам список зараз TObjectList НЕ published property.
см.
TPersistent.DefineProperties ()
TPersistent.DefineProperty ()
TPersistent.DefineBinaryProperty ()
TWriter.WriteListBegin / End
TReader.ReadListBegin / End
Так це я бачив, але думка голову не відвідала - було б проперти - немає проблем. Причому сам батьківський об'єкт TCollectionItem - і в список його об'єктів не запхати. Подивитися чи як в TComponent зроблено?
Дякую за підказку з WriteList.
> Було б проперти - немає проблем
> Список його об'єктів не запхати
це чому ж. см. TReader.ReadCollection, TWriter.WriteCollection
ReadCollection is a helper method used by other reader methods to read a tagged collection value at the current reader Position. ReadCollection iterates through items in a collection so that each item in a collection property has an opportunity to stream out its properties. This method does not write out the number of items and the collection indices, because a user can add or delete items.
Я мав на увазі, що CollectionItem не об'єкт і у нього немає властивості Objects. Зараз як раз дивлюся:
procedure TWriter.WriteCollection (Value: TCollection);
var
I: Integer;
OldAncestor: TPersistent;
begin
OldAncestor: = Ancestor;
Ancestor: = nil;
try
WriteValue (vaCollection);
if Value <> nil then
for I: = 0 to Value.Count - 1 do
begin
WriteListBegin;
WriteProperties (Value.Items [I]);
WriteListEnd;
end;
WriteListEnd;
finally
Ancestor: = OldAncestor;
end;
end;
Там механізм трохи інший - у мене об'єкти різних класів. Він же при завантаженні робить Add і потім ReadProperties. Тут такий фокус не пройде.
> CollectionItem не об'єкт
як це "не об'єкт". це ж спадкоємець TPersistent.
значить, при збереженні колекції для кожного її елемента буде австоматіческі викликаний метод DefineProperties, який можна перевизначити для кожного конкретного класу-спадкоємця TCollectionItem.
І далі. якщо екземпляр-спадкоємець TCollectionItem хоче при збереженні його самого зберегти і свої власні списки або поля (в кач-ве власних св-в), то робить він це точно так же!
в сенсі не компонет. Ну не важливо.
У мене не TCollectionItem потрібно зберігати, з цим немає проблем, а проблеми з тим що він містить, а він містить список різнорідних об'єктів спадкоємців TPersistent (який до речі може розширюватися за рахунок зовнішніх Package plugin-ів). Методу WritePersistentObject немає, тому мабуть доведеться наслідувати все від TComponent і писати в список WriteComponent.
> Містить список різнорідних об'єктів спадкоємців TPersistent
>
для кожного з них ти вільний "вручну" викликати DefineProperties ().
А у ж кожен з них сам запише / прочитає свої індивідуальні св-ва
А як об'єкти то самі конструювати при читанні? Треба ж його клас знати. Знову ж вручну це морока. Список класів заздалегідь не відомий. У TCollection клас визначений (Він навіть його не зберігає мабуть в ресурсі), а TComponent бере зі списку зареєстрованих класів.
> Потрібно ж його клас знати
при записі в потік записуй ім'я класу найпершим св-вом
> Знову ж вручну це морока
Інших способів немає - тольуо "вручну", одного разу визначивши поведінку persistent-прим-ра при виклику його методу DefineProperties ()
> Список класів заздалегідь не відомий
зроби так, щоб він був відомий
кожен з класів в списку зареєструй
інакше завдання (в тому вигляді як ти її задумав) не вирішується
> TComponent бере зі списку зареєстрованих класів
ніщо не заважає клас зареєструвати.
аби існувала його декларація.
Загалом для даного випадку мені простіше успадкувати немає від TPersistent, а від TComponent. Він сам ім'я класу запише. DefineProperties мені втім теж знадобляться - самі ці класи в свою чергу містять дані.
> Ніщо не заважає клас зареєструвати.
Це обов'язково.
в цілому - так
TComponent як спадкоємець дещо полегшить рутинну роботу
Але реєстрація, звичайно, необхідна, тільки вже не класу, а компонента (TRegisterComponent [s])
придивися ще до TComponent.GetChildren ()
в кач-ве досить розумної альтернативи можна відмовитися від використання колекцій на користь св-ва списку TComponent.Components [] - знову ж зменшення рутинної роботи. Раз TComponent вже реалізує список (і управління ним) компонентів, для яких він є власником, гріх ним не скористатися)
TMyObject = class (TComponent)
.
protected
procedure GetChildren (Proc: TGetChildProc); override;
.
end;
.
procedure TMyObject.GetChildren (Proc: TGetChildProc);
var
i: Integer;
begin
for i: = 0 to ComponentCount - 1 do
Proc (Components [i]);
end;
в результаті при збереженні / відновленні якогось компонента автоматично будуть збережені / відновлені всі його "діти"
Я в курсі. Я так вже робив, але на цей раз структура вийшла така: Компонент - Документ (теж компонент) - Документ з даними (спадкоємець) - Дані Root (Collection) - Блоки даних (CollectionItems) - Поля даних (TComponent по видимому) - Власне Дані . І все це неподобство потрібно зберігати.
Пам'ять: 0.75 MB
Час: 0.061 c