Форум: "Начинающим";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];
ВнизДобавление объектов в ComboBox (Tobject(string)) Найти похожие ветки
← →
Nike85 (2007-11-02 15:25) [0]Здравствуйте!
Не могу понять, чем вызвана следующая проблема:
читаю из бд данные - имя записи (name) и строковое представление идентификатора (anrec), добавляю их в расположенный на форме комбобокс (имя - как строку, идентификатор - в список объектов). Однако при дальнейшем выводе идентификатора - выходит абракадабра (пустое сообщение - такое ощущение, что где-то утечка памяти).
Код ниже:
//Чтение данных:
//s1,s2: string;
while not tempQuery1.Eof do
begin
s1:=tempQuery1.FieldByName("name").AsString;
s2:=tempQuery1.FieldByName("anrec").AsString;
ShowMessage(s2);
cmbStatus.Items.AddObject(s1,Tobject(s2));
TempQuery1.Next;
end;
//Вывод данных:
ShowMessage(string(cmbStatus.Items.Objects[cmbStatus.ItemIndex]));
← →
Nike85 (2007-11-02 15:27) [1]в чем проблема? почему теряются данные? Как это можно исправить? Подскажите, пожалуйста, горю.
← →
Kolan © (2007-11-02 15:29) [2]А не заюзать ли тебе TDBLookUpComboBox?
← →
Reindeer Moss Eater © (2007-11-02 15:34) [3]После заполнения списка с объектами, как только выходим за пределы процедуры и все неявные строки (TField.AsString) выходят за пределы видимости и умирают, все объекты в списке начинают указывать на мусор.
← →
Nike85 (2007-11-02 15:36) [4]Как сделать "вечно живущие" объекты? не заводить же для это глобальные переменные? Я пока делаю так - для каждого комбобокса - их уже штуки 4 у меня на форме,я сделал объекты Tstringlist. Но это мне кажется как-то коряво
← →
Reindeer Moss Eater © (2007-11-02 15:37) [5]Переменные не нужны. Нужно явно распределять память под строки
← →
Юрий Зотов © (2007-11-02 15:39) [6]> Nike85 (02.11.07 15:25)
Разве строка - это объект?
Строка имеет управляемое время жизни и как только счетчик ссылок на нее обнуляется, занимаемая ею память автоматически освобождается (и, соответственно, ссылки на нее становятся недействительными). У Вас это происходит со строкой s2 на каждом новом витке цикла.
Используйте Names и Values.
← →
Nike85 (2007-11-02 15:40) [7]To Reindeer Moss Eater © :
Это как, можно по-подробнее? Pchar-ом пользоваться? можно код? Объясните дураку
To Kolan © :
Дблукап не хотелось бы использовать. Да и тут уже дело принципа - как заставить комбобокс хранить свои объекты :))
← →
Reindeer Moss Eater © (2007-11-02 15:41) [8]cmbStatus.Items.AddObject(s1,TObject(StrNew(PChar(s2))));
← →
Nike85 (2007-11-02 15:50) [9]To Юрий Зотов © :
строка - не объект, это не си шарп. Или нет??
To Reindeer Moss Eater ©
Ок, че я где-то подобное уже видел. Создать объект новый надо было. Спасибо, кажется так заработает. Сейчас проверю. А освобождать объекты надо как, например при очистке списка перед его новым заполнением?for i:=cmbStatus.Items.Count-1 downto 1 do
cmbStatus.Items.Objects[i].Free;
Правильно я понимаю или нет?
← →
Nike85 (2007-11-02 15:51) [10]только не даунту 1, а 0 :))
← →
Reindeer Moss Eater © (2007-11-02 15:52) [11]Ну подумай, если память распределялась с помощью StrNew, то чем же надо её освобождать?
← →
Nike85 (2007-11-02 15:56) [12]Возможно вот так?
for i:=cmbStatus.Items.Count-1 downto 0 do
StrDispose(Pchar(cmbStatus.Items.Objects[i]));
cmbStatus.Clear;
А что будет если вызывать Objects[i].Free?
← →
Reindeer Moss Eater © (2007-11-02 15:58) [13]А попробуй.
Зачем Free, если никто Create не делал?
← →
Kolan © (2007-11-02 16:00) [14]Вставлю своё имхо. Данные не надо хронить в ComboBox"е или пользуй DB Aware контрол
или (как сделал бы я) метериализуй объекты из БД и хрони их в отдельном списке. При надобности синхронизируй список с комбо и наоборот…
← →
Nike85 (2007-11-02 16:04) [15]сможет ли Object удалить себя, вызывая Free, даже если обжект представлен Pchar-ом? Конечно, если использовать приведение к пчару, то можно удалять и через strdispose. Только вот вопрос теперь у меня такой, если вызвать Objects[i].Free, хватит ли сил объекту Тобжект корректно удалить себя, даже если внутри него инкапсулирован Пчар, или допустим объект Tform. В каком случае будет выше производительность? - если через strDispose, или через метод Tobject?
← →
Nike85 (2007-11-02 16:08) [16]To Kolan © :
А зачем я буду синхронизировать комбо с внешним списком, если при хранении в комбобоксе данные всегда будут синхронизованы (даже если я буду пересортировывать строки комбо, то автоматом и будут пересортировываться объекты, с ними связанные (а может и не будут :))). Да и внешний список - это еще одна явно объявленная переменная, модуль читать не удобно. Не, мне больше вариант с хранением в комбо нравится
← →
Anatoly Podgoretsky © (2007-11-02 16:09) [17]> Nike85 (02.11.2007 15:36:04) [4]
Глобальную конечно завести можно, она удаляться не будет, но и все объекты будут одинаковы.
← →
Anatoly Podgoretsky © (2007-11-02 16:10) [18]> Reindeer Moss Eater (02.11.2007 15:52:11) [11]
Как чем, с помощью справки конечно, бить ею по голове до полного просветления.
← →
Anatoly Podgoretsky © (2007-11-02 16:10) [19]> Nike85 (02.11.2007 15:56:12) [12]
> А что будет если вызывать Objects[i].Free?
Ой не делай этого, будет больно.
← →
clickmaker © (2007-11-02 16:19) [20]
> [15] Nike85 (02.11.07 16:04)
> сможет ли Object удалить себя, вызывая Free, даже если обжект
> представлен Pchar-ом?
PChar - это PChar, а обжект - это обжект
Первый - указатель на область памяти, где находится просто массив байтов.
Вотрой - тоже по сути указатель, но по этому адресу живет объект некоего класса со свойствами и методами.
Почувствуйте разницу
← →
Kolan © (2007-11-02 17:18) [21]> если при хранении в комбобоксе
Дело в том что комбо — это элемент интерфейса и он не очень то пригоден для хронения данных.
В любом случае даже при использовании комбо, лучьше матеарелизовывать объект(с понятным именем и внятными полями) и сохронять его…
← →
Kolan © (2007-11-02 17:22) [22]
TMyObject = class
private
FName: string;
FAnrec: string; //ХЗ что есть anrec…
public
constructor Create(Name, Anrec: string);
end;//Чтение данных:
//s1,s2: string;
while not tempQuery1.Eof do
begin
with tempQuery1 do
cmbStatus.Items.AddObject(s1, TMyObject.Create(FieldByName("name").AsString,
FieldByName("anrec").AsString));
TempQuery1.Next;
end;
Написание савойств, кода конструктора — дом. задание.
← →
Юрий Зотов © (2007-11-03 23:50) [23]> Nike85 (02.11.07 15:50) [9]
В Delphi строка - это не объект. Это Pointer на Record специального (compiler-magic) типа. Структура такая:
-8: Счетчик ссылок
-4: Длина тела в байтах
0: Тело строки, заканчивающееся нулем (ASCIIZ)
Хранятся строки в динамической памяти, а рулит всей этой фигней компилятор. В частности, он же вставляет код изменения счетчика ссылок и код освобождения памяти, если счетчик ссылок стал нулевым.
Но компилятор - не человек, и даже не ИИ. Поэтому он не понимает, что при выполнении кодаTStrings.AddObject(s1, TObject(s2)
счетчик ссылок в строке s2 должен быть увеличен. Он его и не увеличивает. Поэтому, как только переменная s2 получает новое значение, ее старое значение уничтожается и Objects[i] начинает ссылаться в никуда.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.035 c