Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Строку в объект [D7, XP]


Страницы:   1 2 3 4 5 6

kyn66 ©   (2009-11-12 16:11:00) 

Подскажите, каким способом можно строку вставить в объект , ну например ComboBox ? Нужно к примеру просканировать текущий каталог диска, найденные файлы записать в Combobox, а полный путь к файлу сохранить в объекте. Помню со строками есть проблемы при сохранении в объект. Есть вот такой вариант

....
var
 PS: PString;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
 new(PS);
 PS^ := 'Hello world 1';
 ComboBox1.Items.AddObject('Item1', TObject(PS));
 PS^ := 'Hello world 2';
 ComboBox1.Items.AddObject('Item2', TObject(PS));
 PS^ := 'Hello world 3';
 ComboBox1.Items.AddObject('Item3', TObject(PS));
...

procedure TForm1.FormDestroy(Sender: TObject);
begin
 Dispose(PS);
end;


При доступе к объекту

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 ShowMessage(PString(Combobox1.Items.Objects[0])^); //Hello world 1
end;


возникает ошибка (AV)


Григорьев Антон   (2009-11-13 14:30:00) [61]


> Вот эта строка не совсем понятна. Речь идет о записях впринципе
> или о их содержимом?

О содержимом. Если память под запись выделять и освобождать через GetMem/FreeMem, то освобождаться будет только память, выделенная под саму структуру, а содержищиеся в ней управляемые типы данных должным образом освобождены не будут. А если использовать New/Dispose, то будут, нато только при вызове Dispose не забывать приводить указатель к правильному типу. А вот если в записи есть неуправляемые ссылки на внешние данные (типа того же PChar), то тут уже в любом случае руками освобождать надо.


Ухарь   (2009-11-13 14:19:00) [62]


> kyn66 ©   (13.11.09 13:52) [43]
>
>



> Речь идет о записях впринципе или о их содержимом?


Речь идет о том, что если использовать  New и Dispose, то мы будем иметь дело каждый раз с разной структурой (или строкой, или объектом - не важно, в общем - с разными областями памяти), и на каждом проходе получать новый указатель.
А не добавлять один и тот же адресво все элементы списка.
В случае использования объекта и его конструктора ровным счетом то же самое и происходит, если такой подход по каким то причинам не устраивает, нужно сделать тоже самое, но руками


Leonid Troyanovsky   (2009-11-13 14:18:00) [63]


> kyn66 ©   (13.11.09 13:52) [43]

> >  никаких проблем с управляемыми типами внутри не возникает.

> Вот эта строка не совсем понятна. Речь идет о записях впринципе
> или о их содержимом?

RTFM: Finalize procedure.

--
Regards, LVT.


kyn66   (2009-11-13 13:52:00) [64]


> А AddObject просто сохраняет указатель, он не делает копию
> того, что вы передаёте. В результате вы каждый раз перезаписывали
> строку, уже добавленную в Objects.


Согласен. Я уже и сам до этого додумался, посмотрев внимательно.

>  Если памятью для них управлять с помощью New и Dispose,
>  никаких проблем с управляемыми типами внутри не возникает.


Вот эта строка не совсем понятна. Речь идет о записях впринципе или о их содержимом?


Игорь Шевченко   (2009-11-13 13:42:00) [65]


> Если по поводу частых обращений на  delphimaster.ru, то
>  уже сто раз говорил, что нато это и форум, чтобы здесь
> задавать вопросы и если кто считает нужным - на них отвечать.
>  А не писать глупые ухмылочные намеки! Тем более ветка выбрана
> не для вундеркиндов. (Не все знаете учились на программистов.
> .. Некоторые учились этому через книги, вопросы, форумы
> и т.д.). Т.ч. коллеги, давайте не будем умничать, а отвечать
> по существу, если есть желание !!!


http://ln.com.ua/~openxs/articles/smart-questions-ru.html

читать до полного просветления.


Григорьев Антон   (2009-11-13 13:38:00) [66]


> Использование классов (очень понравился вариант). В нем
> я могу хранить много разных данных.

А параллельно с этим хранится ещё куча данных, унаследованных от TObject, а также служебной информации. Если хотите "много и просто", используйте лучше record. Если памятью для них управлять с помощью New и Dispose, никаких проблем с управляемыми типами внутри не возникает.

> А вот по поводу PChar, то вроде в [0] все с этого и начиналось.

Там не PChar был, а PString. И в одну и ту же строку вы записывали разные значения. А AddObject просто сохраняет указатель, он не делает копию того, что вы передаёте. В результате вы каждый раз перезаписывали строку, уже добавленную в Objects.


kyn66   (2009-11-13 13:32:00) [67]


> SergP ©   (13.11.09 13:25) [39]
>
>Или у тебя просто пример неудачный?


ТОбою не понята суть вопроса. Вопрос был из области AddObjectс передачей строки в качестве параметра. Он впринципе уже решен. Почитай ветку полностью, могет пригодится ;)


SergP   (2009-11-13 13:25:00) [68]


> Подскажите, каким способом можно строку вставить в объект
> , ну например ComboBox ? Нужно к примеру просканировать
> текущий каталог диска, найденные файлы записать в Combobox,
>  а полный путь к файлу сохранить в объекте. Помню со строками
> есть проблемы при сохранении в объект.


А зачем все это?
Если рассуждать в пределах данного примера, то:
полный путь к файлу = путь к каталогу +'\' +имя файла
А если ты сканируешь определенный каталог, то значит путь к этому каталогу  для всех файлов одинаковый...

Или у тебя просто пример неудачный?


kyn66   (2009-11-13 13:14:00) [69]


> Григорьев Антон ©   (13.11.09 12:57) [37]


Спасибо Антон за ликбез. Приятно читать умные слова. Из всего здесь выше сказанного я принял для себя  2 варианта. 1) Параллельное хранение данных в TStringList ; 2) Использование классов (очень понравился вариант). В нем я могу хранить много разныхданных. Главное не забывать удалять ссылки на объекты. Вот такой вариан применил себе. Испробовано на 2-х типах данных. ВОт тестовый пример. Ничего лишнего и все работает на ура!

...
type
 TStr = class
   private
     FName : string;
     FOlds : Integer;
   public
     property Name: String read FName;
     property Olds: Integer read FOlds;
     constructor Create(Const name: string; Const olds : Integer);
 end;
...
 procedure FreeObjects(const strings: TStrings) ;
implementation

{$R *.dfm}

constructor TStr.Create(Const name: string; Const olds : Integer);
begin
 FName := name;
 FOlds := olds;
end;

procedure TForm1.FreeObjects(const strings: TStrings) ;
var
 idx : integer;
begin
 for idx := 0 to Pred(strings.Count) do
 begin
   strings.Objects[idx].Free;
   strings.Objects[idx] := nil;
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 FreeObjects(ComboBox1.Items);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 ComboBox1.Items.AddObject('Item 1', TStr.Create('ObjectItem 1', 1));
 ComboBox1.Items.AddObject('Item 2', TStr.Create('ObjectItem 2', 2));
 ComboBox1.Items.AddObject('Item 3', TStr.Create('ObjectItem 3', 3));
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
 ShowMessage(TStr(ComboBox1.Items.Objects[ComboBox1.ItemIndex]).Name + #10#13 +
             IntToStr(TStr(ComboBox1.Items.Objects[ComboBox1.ItemIndex]).Olds));
end;
....

А вот по поводу PChar, то вроде в [0] все с этого и начиналось.

> Ваши строки искажаются потому, что string - это управлемый
> тип, т.е.

Не совсем искажаются, а при кликах по любому Items выдает одно и то же значение "объекта"

Да и сообщение [16] как то насторожило и заставило подумать почему так?

В конечном итоге можно было остановиться на использовании TStringList с синхронизацией.... Но хочется изучить и применить нечто новое. Интересовали новые, другие доступные механизмы.


Григорьев Антон   (2009-11-13 12:57:00) [70]


> kyn66 ©   (13.11.09 11:35) [36]
> (Не все знаете учились на программистов... Некоторые учились
> этому через книги, вопросы, форумы и т.д.

Я вот тоже не учился на программиста :) Поэтому давайте с самого начала и вместе :)

Ваши строки искажаются потому, что string - это управлемый тип, т.е. компилятор следит за тем, сколько ссылок есть на строку, и при уничтожении всех ссылок освобождает память, выделенную под строку. Но интеллекта компилятора хватает только на то, чтобы отслеживать ссылки, явно объявленные как string. Когда вы приводите строку к TObject, вы получаете ещё одну фактическую ссылку на эту строку, но так она не имеет тип string, то компилятор игнорирует её при подсчёте. Теперь, как только все остальные ссылки будут освобождены, память, выделенная для строки, будет помечена как неиспользуемая, и в любой момент она может быть распределена для других нужд. А ссылка на эту память у вас осталась. В результате, когда вы обращаетесь по ней, то получаете более-менее случайный мусор.

Чтоюы этого не происходило, надо не приводить управляемые ссылки к левым типам. Одно из решений вам подсказали: использование классов. Классы - типы неуправляемые, никто ссылки на них не считает, сами никогда не удалятся, так что левые ссылки на них хранить достаточно безопасно. А уж в класс можно засунуть явно объявленную string, и компилятор правильно её посчитает. Но это - лишний расход ресурсов, как вам уже сказали.

Чтобы этого избежать, можно записывать в Objects ссылку на неуправляемую строку, т.е. на PChar. Только надо не забываь перед этим выделять для такой строки память (с помощью, например, StrNew), а потом, когда строка станет ненужной, удалять. Если вы не удалите такую ссылку вручную, то получите утечку памяти. Так что этот вариант требует некоторой внимательности. Как, впрочем, и вариант с использованием дополнительного TStringList: там тоже надо следить, чтобы списки были синхронизированы.


kyn66   (2009-11-13 11:35:00) [71]


> Ну не все же разжевывать...


Если по поводу частых обращений на  delphimaster.ru, то  уже сто раз говорил, что нато это и форум, чтобы здесь задавать вопросы и если кто считает нужным - на них отвечать. А не писать глупые ухмылочные намеки! Тем более ветка выбрана не для вундеркиндов. (Не все знаете учились на программистов... Некоторые учились этому через книги, вопросы, форумы и т.д.). Т.ч. коллеги, давайте не будем умничать, а отвечать по существу, если есть желание !!!


Dennis I. Komarov   (2009-11-13 11:28:00) [72]


> Какой этой фразой ?

[28]

> Что вы все загадками говорите?

Ну не все же разжевывать...


kyn66   (2009-11-13 11:08:00) [73]


> Dennis I. Komarov ©   (13.11.09 10:53) [33]
> Так и понимай, то что до тебя хотели донести этой фразой
> ты не осознал...


Какой этой фразой? Что вы все загадками говорите? Или нормально сказать гонор не позволяет?

В конечном итоге решение найдено. Цель достигнута после [15], спасибо автору за наводку + прочитка материала http://delphi.about.com/od/vclusing/a/items_addobject.htm. Тему можно закрыть . Всем спасибо!


Dennis I. Komarov   (2009-11-13 10:53:00) [74]

Так и понимай, то что до тебя хотели донести этой фразой ты не осознал...


kyn66   (2009-11-13 10:09:00) [75]


> Dennis I. Komarov ©   (13.11.09 10:05) [31]
> > kyn66 ©   (13.11.09 09:49) [30] Ты не познал сути учения.
> ..


Это как понять?


Dennis I. Komarov   (2009-11-13 10:05:00) [76]


> kyn66 ©   (13.11.09 09:49) [30]

Ты не познал сути учения...


kyn66   (2009-11-13 09:49:00) [77]


> Dennis I. Komarov ©   (13.11.09 09:48) [28]
>
> delphimaster.ru :)


В том числе... ;)


Dennis I. Komarov   (2009-11-13 09:48:00) [78]


> Он должен знать и быстро определить где сможет получить
> ответ на тот или иной вопрос.

delphimaster.ru :)


kyn66   (2009-11-13 09:48:00) [79]


> Юрий Зотов ©   (13.11.09 08:38) [26]


Вот она, задумка - http://delphi.about.com/od/vclusing/a/items_addobject.htm
store one more additional string along the one displayed to the user.


kyn66   (2009-11-13 09:12:00) [80]


> Юрий Зотов ©   (13.11.09 08:38) [26]



> А зачем? Разве не проще и не безопаснее (в смысле ошибок)
> делать именно так, как Вы вначале и делали - хранить вторые
> строки в отдельном списке и сопоставлять их по индексу?


Этот вариант был придуман давно. Просто я не думал что он совсем грамотный и "современный". А раз Мастер его утверждает, то на нем и останусь.


> А во-вторых что ты так зациклился на AddObject, что другие
> варианты не признаёшь?


Да нет, просто хотелось его иметь в своей копилке вариантов применения в определенных ситуациях. Когда нас учили в институте, то говорили, что инженер не обязан все держать в голове. Он должен знать и быстро определить где сможет получить ответ на тот или иной вопрос. Вот для этого копилка наработок и присутствует.


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо