Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как хранить в памяти несколько TStrings???


Автор: padla 14.8.2006, 09:50
Моя проблема:
есть TreeView и RichEdit. Мне нужно для каждого элемента TreeNode хранить RichEdit.Lines, и соответственно загружать при щелчке на ноде.

Я так прикинул - выделяем в куче память, кидаем в нее содержимое RichEdit.Lines, ссылку на данные в куче кидаем в TreeNode.Data. Казалось бы все просто, но не получается это реализовать.

Уважаемые гуру, помогите пожалуйста!

Автор: dvamaster 14.8.2006, 09:53
Код

...
TStrings(TreeNode.Data) := RichEdit.Lines;
...
RichEdit.Lines := TStrings(TreeNode.Data);
...


Добавлено @ 09:56 
Не забывай потом ручками почистить все TStrings(TreeNode.Data)

Код

  TStrings(TreeNode.Data).Destroy;


Для всех TreeNode

Автор: Snowy 14.8.2006, 10:03
dvamaster, нет, так неправильно.

Автор: ivashkanet 14.8.2006, 10:11
Snowy, а чё так? smile
Извините что леузу не в свой монастырь.
Но строки, обычно, не ссылочный тип данных. И получить ссылку на конкретню строку не получится.
(Если не пользоваться именно !ссылками!)
При выполнении кода newString = oldString создается новый экземпляр строки и в него копируется все данные из строки oldString. По этому это будут разные строки smile 
P.S. Это так в .Net  smile Как у вас я точно не знаю, но должно быть так smile
P.P.S. Если я СОВСЕМ не прав, то сильно меня не ругайте, а считайте пост за офтопп. (Но ситуация описанная в первом посте очень смахивает на эту smile )

Автор: Snowy 14.8.2006, 10:15
В том то и дело, что нужно запоминать строку, а не ссылку на неё.
Иначе при чистке рича, накроются и данные.

Добавлено @ 10:19 
Вот так мы запомним данные, а не ссылку:
Код

var
  p: PString;
begin
  New(p); p^ := RichEdit.Lines.Text;
  TreeNode.Data := p;
end;

...

RichEdit.Lines.Text := PString(TreeNode.Data)^;

Автор: Fedia 14.8.2006, 10:27
ivashkanet, 
Цитата(ivashkanet @  14.8.2006,  10:11 Найти цитируемый пост)
newString = oldString

newString := oldString; в Delphi в этом случае указатель на строку oldString создается. Это не .Net smile

Автор: padla 14.8.2006, 10:46
Хм... У меня появилась еще одна мысль:
а если сопоставить дереву TreeView дерево XML???

Думаю прокатит.... и не так критично к памяти.

Автор: ivashkanet 14.8.2006, 10:47
Цитата(Fedia @  14.8.2006,  10:27 Найти цитируемый пост)
в Delphi в этом случае указатель на строку oldString создается. Это не .Net 

Я ж не против  smile 
Просто хотел помочь  smile
Жалко что не получилось  smile 

Автор: Snowy 14.8.2006, 10:59
Цитата(Fedia @  14.8.2006,  10:27 Найти цитируемый пост)
newString := oldString; в Delphi в этом случае указатель на строку oldString создается. Это не .Net
С чего вдруг? Строка полностью копируется.

Автор: Fedia 14.8.2006, 11:15
Цитата(Snowy @  14.8.2006,  10:59 Найти цитируемый пост)
Цитата(Fedia @  14.8.2006,  10:27 )    
newString := oldString; в Delphi в этом случае указатель на строку oldString создается. Это не .Net    
С чего вдруг? Строка полностью копируется.

По данным литературы, которой я на данным момент располагаю, в этом случае увеличивается счетчик ссылок строки oldString.
Код

procedure TConvertDBGridDemoMainForm.Button1Click(Sender: TObject);
var
  s: string;
begin
  s:='test'; //выделяется память, необходимая для размещения строки
  s:=OldString; //увеличивается счетчик ссылок строки OldString
  //предпологается что строка OldString уже имеет значение
  SetLength(s, 4); //выделяется память
end;

Цитата(ivashkanet @  14.8.2006,  10:47 Найти цитируемый пост)
Просто хотел помочь

Меньше всего в этом сомневался smile Сейчас меня побьют за оффтоп  smile  

Автор: Snowy 14.8.2006, 11:31
Fedia, Глядя на этот пример, создаётся впечатление о том, что это контекст описания работы внутренней реализации.
Потому что сам по себе кусок - полный бред.
А внутренняя реализация - это совершенно другой вопрос. То как дельфи оптимизирует наши действия - не должно нас беспокоить.
Сейчас мы говорим про логику построения списка.

Автор: dvamaster 14.8.2006, 11:34
Цитата(dvamaster @  14.8.2006,  12:53 Найти цитируемый пост)
...
TStrings(TreeNode.Data) := RichEdit.Lines;
...
RichEdit.Lines := TStrings(TreeNode.Data);
...


Snowy, зато работает

Добавлено @ 11:35 
Так TObject есть указатель, а он размерностью с Pointer, что и есть Data

Добавлено @ 11:35 
Сам понимаю, что это не красиво, но помогает

Автор: Alexeis 14.8.2006, 11:37
Цитата(Fedia @  14.8.2006,  11:15 Найти цитируемый пост)
По данным литературы, которой я на данным момент располагаю, в этом случае увеличивается счетчик ссылок строки oldString.

Совершенно верно, но в случае удаления исходной строки, предварительно делается копия для каждой ссылки.

Автор: Fedia 14.8.2006, 11:39
Да, копируется. Сейчас проверил. В этом примере выдается сообщение: "test1".
Код

var
  s1, s2: string;
begin
  s1:='test1';
  s2:=s1;
  SetLength(s1, Length(s1)-1);
  ShowMessage(s2);
end;
 
Хех. А ведь я был почти уверен в своей правоте !

Автор: Snowy 14.8.2006, 11:41
dvamaster, я ж говорю - это указатель.
А нужно строку хранить, а не указатель.
Если использовать указатель на RichEdit.Lines, то при чистке рича почистится и по указателю.
А смысл в том, что рич один. А узлов с данными много. И в каждый должен попасть разный текст, а не один и тот же указатель на рич.

Автор: dvamaster 14.8.2006, 11:43
Snowy, согласен с этим, я просто показал возможность выхода из ситуевины

Код

TStrings(TreeNode.Data) := TStringList.Create;

Автор: Snowy 14.8.2006, 11:44
alexeis1, я и грю. По внутренней реализации идёт оптимизация через счётчик ссылок.
А развязывается потом - при изменении одного из экземпляром.
Но нас это не должно беспокоить - внутренняя реализация - это уже детали для знатоков.

Добавлено @ 11:45 
dvamaster, достаточно сохранить просто текст.
А создавая новый лист, нужно уже через assign запоминать.
Просто с текстом быстрее и оптимальнее по памяти.

Автор: Fedia 14.8.2006, 11:46
Цитата(Snowy @  14.8.2006,  11:31 Найти цитируемый пост)
Потому что сам по себе кусок - полный бред.

Практический смысл этот кусок кода и не нес .

Цитата(alexeis1 @  14.8.2006,  11:37 Найти цитируемый пост)
Совершенно верно, но в случае удаления исходной строки, предварительно делается копия для каждой ссылки.

Т.е. в моем примере делается копия строки в момент SetLength(s1, Length(s1)-1) ?

Добавлено @ 11:50 
Цитата(Snowy @  14.8.2006,  10:59 Найти цитируемый пост)
С чего вдруг? Строка полностью копируется.

Без обид, но строка в этот момент, получается что, не копируется. Я ведь приводил этот пример для сравнения с VS .Net.

Автор: Snowy 14.8.2006, 11:53
Я ж и говорю - это уже детали реализации - просто оптимизация.
Реально копирование происходит только при расхождении содержимого.
Логически - в момент присваивания.

Цитата(Fedia @  14.8.2006,  11:46 Найти цитируемый пост)
Практический смысл этот кусок кода и не нес .
Я про камменты.

Автор: Fedia 14.8.2006, 11:59
Цитата(Snowy @  14.8.2006,  11:53 Найти цитируемый пост)
Я ж и говорю - это уже детали реализации - просто оптимизация.
Реально копирование происходит только при расхождении содержимого.
Логически - в момент присваивания.

В общем, мы говорили о разных вещах, и спор не имел никакого основания. Еще раз извиняюсь за оффтоп.

Автор: Snowy 14.8.2006, 12:06
Просто в данном конкретном примере речи о дублировании ссылки вообще не идёт, т.к. Lines.Text - это не строка, а пропертя.
Поэтому копирование происходит в момент присваивания.

Автор: dvamaster 14.8.2006, 12:17
Цитата(Snowy @  14.8.2006,  14:44 Найти цитируемый пост)
Просто с текстом быстрее и оптимальнее по памяти. 

Респект

И вообще я лично тебя уважаю и ценю

Автор: Fedia 14.8.2006, 12:24
Цитата(Snowy @  14.8.2006,  12:06 Найти цитируемый пост)
Просто в данном конкретном примере речи о дублировании ссылки вообще не идёт, т.к. Lines.Text - это не строка, а пропертя.
Поэтому копирование происходит в момент присваивания.

Я ж говорю о речь разных вещах шла. Я в примере приводил просто переменную. А если в контексте Lines.Text, то твоя правда. С мастером не поспоришь ...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)