Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];

Вниз

Экземпляр класса   Найти похожие ветки 

 
faiwer ©   (2009-09-24 11:48) [0]

[code]function TFotoViewer.Add(caption: string; id: smallint): boolean;
var im: TImageBox;
begin
im:=TImageBox.Create(self);
im.Parent:=panel;
im.Caption:=caption;
im.OnClick:=SetCurIndex;
im.OnDblClick:=self.OnDblClick;
im.Left:=panel.Width+1;
Items.Add(im);
if self.Showing then ItemIndex:=Items.Count-1;
end;[/code]

где Items это Items: TList<TImageBox>; а TImageBox это компонент на основе панели, рисунка и метки. собственно вопрос, а что происходит с Im после окончания процедуры Add? и вообще такой код нормальный с точки зрения распределения памяти? TList при Destroy-е сам удаляет все своим Items которые TImageBox, а вот что из себя представляет Im я не понимаю. Это указатель на размещение экземпляра на в ОЗУ? в общем такой код оптимален или мне надо его переделывать?

P.S.CodeGear 2009


 
Сергей М. ©   (2009-09-24 12:13) [1]


> TList при Destroy-е сам удаляет все своим Items которые
> TImageBox


Ничего он не удаляет.


> что из себя представляет Im я не понимаю


Переменная объектного типа - специальный типизированный указатель.


> указатель на размещение экземпляра на в ОЗУ?


Не в ОЗу , а в ВАП процесса.


> надо его переделывать?


Надо. Иначе будут утечки памяти.
Самое простое - заменить TList на TObjectList. При его разрушении он будет ответстверен за разрушение объектов в своем списке Items


 
faiwer ©   (2009-09-24 12:21) [2]

Сергей М., а если этот код оставить таким же но переделать Destroy вот так:
if Items.Count>0 then
 for i:=Items.Count-1 downto 0 do begin
  Items.Items[i].Free;
  Items.Delete(i);
 end;
Тогда утечек памяти не будет?


 
Сергей М. ©   (2009-09-24 12:32) [3]


> faiwer ©   (24.09.09 12:21) [2]


Как ты его переделывать собрался ? Править исходники TList что ли ?


 
faiwer ©   (2009-09-24 12:37) [4]

нее.
я пишу для своей программы компонент TFotoViewer
у него разумеется свой Destroy; и я в этом Destroy освобождаю каждый компонент (а надо ли? или он может автоматом?)
на данный момент умну так:

destructor TFotoViewer.Destroy;
begin
Clear;
panel.free;
inherited Destroy;
end;

Но могу сделать так:

destructor TFotoViewer.Destroy;
var
i: byte;
begin
Clear;
if Items.Count>0 then
 for i:=Items.Count-1 downto 0 do begin
  Items.Items[i].Free;
  Items.Delete(i);
 end;
panel.free;
inherited Destroy;
end;


 
Сергей М. ©   (2009-09-24 12:42) [5]


> faiwer ©   (24.09.09 12:37) [4]


Я не понял, ЧТО мешает задействовать TObjectList вместо TList ?


 
faiwer ©   (2009-09-24 12:47) [6]

items: TObjectList<TImageBox>

вот такой? если я его буду использовать он будет при Delete,Destroy сам удалять их? мне просто будет достаточно вызвать Delete(i) и Destroy?


 
Сергей М. ©   (2009-09-24 12:56) [7]

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Generics_Collections_TObjectList.html


 
faiwer ©   (2009-09-24 14:03) [8]

задействовал TObjectList вместо TList, и всё бы хорошо, но теперь вот такая конструкция:

function TFotoViewer.Add(caption: string; id: smallint): boolean;
var num: smallint;
begin
num:=Items.Add(TImageBox.Create(self));
...
Items[num].OnClick:=SetCurIndex;
...
end;

procedure TFotoViewer.SetCurIndex(Sender: TObject);
begin
if Sender is TImageBox then ItemIndex:=Items.IndexOf(Sender as TImageBox);
Click;
end;

Перестала работать. Грубо говоря попытка получить Items.IndexOf(Sender as TImageBox)  стало приводить в ошибке памяти. Стоит только поменять описание Items на обычный TList<TImageBox>, и Items:=TObj... на обычный TList<TImageBox> как код работает на ура.

Ошибка происходит в следующем. При клике на ImageBox я должен получить его ID в списке Items, для того чтобы мог его выбрать. раньше IndexOf возвращало как раз индекс этого ImageBox в массиве, сейчас просто ошибка памяти (Acces Violation).

Могу скинуть файл целиком.


 
faiwer ©   (2009-09-24 14:26) [9]

procedure TFotoViewer.SetCurIndex(Sender: TObject);
var
i: smallint;
begin
for i := 0 to Items.Count - 1 do
begin
 if sender=items.Items[i] then begin
  ItemIndex:=i; Exit;
 end;
end;
Click;
end;


написал СВОЙ IndexOf, заработало... не знаю насколько это оптимально, но так лучше чем никак :D


 
Сергей М. ©   (2009-09-24 14:39) [10]

Ты вот скажи, за каким лешим тебе в дан.ситуации потребовались дженерики ?

Чем не угодило обычное объявление

Items: TObjectList;

?


 
faiwer ©   (2009-09-24 14:48) [11]

не люблю списки из указателей :) мне бы пришлось по всему коду кидать чтото вроде @ ^ ( ... as TImageBox). и прочее. этой мой первый компонент, к тому же для дела, и я решил без лишнего геммороя


 
Leonid Troyanovsky ©   (2009-09-24 15:44) [12]


> faiwer ©   (24.09.09 14:48) [11]

> этой мой первый компонент


> i: smallint;

За такое руки укорачивают.

> TImageBox

На зачем там панель? Картинка и текст не требуют окна.
Даже TImageList хватит.

--
Regards, LVT.


 
faiwer ©   (2009-09-24 15:55) [13]

[quote]> i: smallint;

За такое руки укорачивают.[/quote]
why? умня максимальное количество этих экземпляров будет штук 30-40 не более, обычно штуки 2-3. режил на всякий пожарный аж smallint поставить. зачем мне integer? или я чтото не понимаю?
[quote]На зачем там панель? Картинка и текст не требуют окна.
Даже TImageList хватит.[/quote]
Главный компонент это TScrollBox, на нём 1 Panel, на ней куча TImageBox (панелька на которой имейдж, и под которым лейбл - название рисунка), с равнением "слева", у скроллбокса запретен вертикальный скролл, активен только горизонтальный. Панели задаётся суммарный размер всех входящих в неё имейджбоксов, и так как она перестаёт влазить в скроллбар, на нём появляется скролл. Очень специфичный компонент, но чтобы понять зачем мне нужен именно такой компонент надо видеть ту прогу для которой я его пишу :D.
Над ним ещё работать и работать, выглядит он пока так:
http://pics.kz/s2/ae/2a/dd/e9/ae2adde99fc3149676a01f7d0c8aba93.jpg


 
Leonid Troyanovsky ©   (2009-09-24 16:17) [14]


> faiwer ©   (24.09.09 15:55) [13]

> штук 30-40 не более, обычно штуки 2-3. режил на всякий пожарный
> аж smallint поставить. зачем мне integer? или я чтото не
> понимаю?

А зачем тогда T/Object/List? И делал бы Image1..Image3
Если уж впряг TList, то будь любезен Integer.

> Главный компонент это TScrollBox, на нём 1 Panel,

Вот этой панели и достаточно, другие - пустая трата ресурсов.

--
Regards, LVT.


 
Сергей М. ©   (2009-09-24 16:18) [15]


> не люблю списки из указателей


Какие нафих указатели ?)
Ими и близко даже не пахнет, ни с дженериками ни без оных.

TFotoViewer = class(..)
private
..
 FItems: TObjectList;
..
protected
..
 procedure AfterConstruction; override;
 procedure BeforeDestruction; override;
..
public
..
 function Add(caption: string; id: smallint): boolean;
..
end;

..

procedure TFotoViewer.AfterConstruction;
begin
 inherited;
 FItems := TObjectList.Create;
end;

procedure TFotoViewer.BeforeDestruction;
begin
 FItems.Free;
 inherited;
end;

function TFotoViewer.Add(caption: string; id: smallint): boolean;
var
 obj: TImageBox;
begin
 obj := TImageBox.Create(nil);
 with obj do
 begin
 ..
   FItems.Add(obj);
 ..
 end;
end;

procedure TFotoViewer.SetCurIndex(Sender: TObject);
begin
..
  ItemIndex:=FItems.IndexOf(Sender);
..
end;


 
faiwer ©   (2009-09-24 16:27) [16]


> А зачем тогда T/Object/List? И делал бы Image1..Image3
> Если уж впряг TList, то будь любезен Integer.

Image1,Image2,...,Image20? нафига? мне что с ними в списке указателей как в 7 классе по паскалю работать? боюсь тогда баги я буду отлавливать до конца века... да и вообще где вы видели простой юзерский комп. который способен загрузить 32767 рисунка 100х100 из JPG за 1-2 секунды? о_О...

[quote]Вот этой панели и достаточно, другие - пустая трата ресурсов.[/quote]
вот тут согласен. но пока для меня энто слишком сложно, там много мелочей, в том числе и дизайнерских :D


 
Leonid Troyanovsky ©   (2009-09-24 16:30) [17]


> Сергей М. ©   (24.09.09 16:18) [15]

>  function Add(caption: string; id: smallint):

Во.. Опять smallint :)

А чего не Constructor/Destructor?
Или оное уже не модно?

--
Regards, LVT.


 
faiwer ©   (2009-09-24 16:30) [18]

Сергей М., хм, действительно не пахнет, а в чём преимущества данного кода перед TObjectList<..>? и почему он вам всем так не понравился? :D


 
Leonid Troyanovsky ©   (2009-09-24 16:32) [19]


> faiwer ©   (24.09.09 16:27) [16]

> Image1,Image2,...,Image20? нафига? мне что с ними в списке
> указателей как в 7 классе по паскалю работать? боюсь тогда
> баги я буду отлавливать до конца века...

Integer.
Integer forever.

--
Regards, LVT.


 
Сергей М. ©   (2009-09-24 16:32) [20]


> в чём преимущества данного кода перед TObjectList<..>?


Это я у тебя хотел спросить, за каким тебе понадобились дженерики в данном случае)


> почему он вам всем так не понравился?


Потому что стрельба из пушки по воробьям)


 
faiwer ©   (2009-09-24 16:35) [21]

Это я у тебя хотел спросить, за каким тебе понадобились дженерики в данном случае)
1 раз я таки проставил это багованое чюдо, надо потестить новые вкусности в нём )
2 проще писать код ;)
Потому что стрельба из пушки по воробьям)
спору нет ;) но хуже же всё равно не будет
Leonid Troyanovsky, так чем же плох SmallInt если он взаимодействует с Integer-ом? ) может мне просто жалко 2 лишних байта ;)


 
Сергей М. ©   (2009-09-24 16:40) [22]


> проще писать код


Ты бы лучше озаботился изучением возможностей встроенного отладчика, чем какой-то там сомнительной "простотой")

А то ведь получается, что код ты настрогал, а как он работает - нишиша не понимаешь)

Да еще и демагогию про ОЗУ, указатели и лишние байты тут разводишь)


 
Сергей М. ©   (2009-09-24 16:42) [23]

Ты зачем self-то указал в конструкторе TImageBox"а ?
На всякий случай что ли, "щоб було" ?)


 
faiwer ©   (2009-09-24 16:45) [24]

Сергей М.
всё проще, когда я пишу self. мне делфи список полей и методов предлагает, а я уже там выбираю или ищу что-нибудь подходящее ;) обычно я тут же убираю self, но иногда забываю... чистить компоненту я буду когда её допишу ;)


 
Сергей М. ©   (2009-09-24 16:46) [25]

Коль уж их родителем делаешь панель, так уж сделай ее и владельцем)

Тогда все эти выкрутасы с листами и обжектлистами будут попросту нафих не нужны - все твои имиджбоксы и так уже являются элементами списка Components объекта-панели. Ну и , соотв-но, панель будет ответсвенна за автоматическое разрушение своих имиджбоксов при своем разрушении.


 
Сергей М. ©   (2009-09-24 16:48) [26]


> faiwer


Компонент - он отродясь мужского рода)


 
Anatoly Podgoretsky ©   (2009-09-24 16:49) [27]

> faiwer  (24.09.2009 16:35:21)  [21]

> мне просто жалко 2 лишних байта

Ибудешь проклят в аду.


 
faiwer ©   (2009-09-24 16:49) [28]

Тогда все эти выкрутасы с листами и обжектлистами будут попросту нафих не нужны - все твои имиджбоксы и так уже являются элементами списка Components объекта-панели. Ну и , соотв-но, панель будет ответсвенна за автоматическое разрушение своих имиджбоксов при своем разрушении.
хм, а это идея, спс... правда стока кода переписывать... :)


 
Сергей М. ©   (2009-09-24 16:50) [29]


> стока кода переписывать


А кому сейчас легко ?)


 
Anatoly Podgoretsky ©   (2009-09-24 16:51) [30]

> faiwer  (24.09.2009 16:49:28)  [28]

Не переписывать столько кода нужно, а не нужно столько кода писать.


 
faiwer ©   (2009-09-24 16:53) [31]


> Не переписывать столько кода нужно, а не нужно столько кода
> писать.

o_O дык я итак по минимальному пишу ;) всё равно много получается. когда хочешь сделать так чтобы пользователю было удобнее, появляется много дополнительных функций, обработчиков и прочего. зато потом куда не ткни, что не нажми, вылазиет всё по стандарту :D


 
Сергей М. ©   (2009-09-24 16:55) [32]


> зато потом куда не ткни, что не нажми, вылазиет всё по стандарту


Угу.
"Стандарные" грабли - AV)


 
Омлет   (2009-09-24 19:00) [33]

Похоже все так начинают - с кучи Image"ов.

> да и вообще где вы видели простой юзерский комп. который способен загрузить 32767 рисунка 100х100 из JPG за 1-2 секунды? о_О...

TImage в количестве 32767 - не дай бог такое приснится... А если каждый на отдельной панельке да еще и с лейблом, можно вообще не проснуться.


 
faiwer ©   (2009-09-24 19:15) [34]

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


 
Омлет   (2009-09-24 19:25) [35]

> faiwer ©   (24.09.09 19:15) [34]

А на чем TImage рисует по-твоему?


 
Leonid Troyanovsky ©   (2009-09-24 19:28) [36]


> faiwer ©   (24.09.09 19:15) [34]

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

Cын ошибок трудных.

--
Regards, LVT.


 
faiwer ©   (2009-09-24 19:56) [37]

в общем решил остаться с TObjectList<>, хуже от этого не будет, займусь более полезными на данный момент вещами. по работе с этим компонентом осталось только сделать метод Swap(item1,item2: smallint);
вот только любые попытки сделать чтото вроде этого:
c:=Items[item1];
items[item1]:=items[item2];
items[item2]:=c;

да и вообще любая попытка items[x]:= убивает компонент, которые был в ней прописан...
есть идеи как это можно реализовать? )


 
Омлет   (2009-09-24 20:00) [38]

> есть идеи как это можно реализовать?

Не использовать дженерики.


 
faiwer ©   (2009-09-25 01:12) [39]

function TFotoViewer.Swap(item1: SmallInt; item2: SmallInt): boolean;
var
temp: TImageBox;
lnum: smallint;
begin
result:=false;
if (item1<0) or (item2<0) or (item1>items.Count-1) or (item2>items.Count-1)
 then Exit;

items.OwnsObjects:=false;
 if ItemIndex=item1 then FItemIndex:=item2 else
  if ItemIndex=item2 then FItemIndex:=item1;

 lnum:=Items[item1].Left;
 Items[item1].Left:=Items[item2].Left;
 Items[item2].Left:=lnum;

 temp:=Items[item1];
 Items[item1]:=Items[item2];
 Items[item2]:=temp;

items.OwnsObjects:=true;
result:=true;
end;


Всё оказалось проще. Если отключить OwnsObjects, то объект при переназначении \ удалении не уничтожается, что позволяет его нам перехватить ;)


 
Сергей М. ©   (2009-09-25 08:35) [40]


> Если отключить OwnsObjects, то объект при переназначении
> \ удалении не уничтожается


Сказка про белого бычка.
Нафига, спрашивается, отключать OwnsObjects, если в этой функциональности и есть ключевой смысл использования TObjectList ?)


> есть идеи как это можно реализовать?


Прежде чем лепить код, справку надо читать. До просветления. Или до посинения. Кому как)
Там черным по-нерусски написано про метод Exchange.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.006 c
1-1222762776
DVM
2008-09-30 12:19
2009.11.08
Base64 кодирование и UnicodeString


15-1252276329
KilkennyCat
2009-09-07 02:32
2009.11.08
TTreeNode с Визибле-Невизибле


2-1253710111
webpauk
2009-09-23 16:48
2009.11.08
Неувязка с Parent


2-1253123104
GlowSolnce
2009-09-16 21:45
2009.11.08
TADOQuery + Access + Delete


2-1253726909
Алексей Петров
2009-09-23 21:28
2009.11.08
обновление программы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский