Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.22.249.158] |
|
Сообщ.
#1
,
|
|
|
Добрый день!
Создан дочерний компонент по схеме: unit MyChildComponent; interface uses Windows, Messages, SysUtils, Variants, Classes; type TMyChildComponent = class(TComponent) private { Private declarations } FParentComponent : TMyComponent; protected { Protected declarations } public { Public declarations } constructor Create(AOwner : TComponent); override; destructor Destroy; override; published { Published declarations } property ParentComponent : TMyComponent read FParentComponent write FParentComponent; end; procedure Register; implementation constructor TMyChildComponent.Create(AOwner: TComponent); begin inherited Create(AOwner); FParentComponent := TMyComponent.Create(Self); end; destructor TMyChildComponent.Destroy; begin if not Assigned(FParentComponent) then FreeAndNil(FParentComponent); inherited; end; procedure Register; begin RegisterComponents('test', [TMyChildComponent]); end; end. Свойство ParentComponent в виде выпадающего списка находит родительский компонент TMyComponent, из которого читаются некоторые параметры в дочерний компонент TMyChildComponent. Компилируются компоненты TMyChildComponent и TMyComponent нормально, на форме в realtime TMyChildComponent прекрасно видит TMyComponent. Далее если положить эти компоненты на форму в новом проекте, запустить его, закрыть и попытаться закрыть сам проект - выдается ошибка: --------------------------- Error --------------------------- Invalid pointer operation. --------------------------- OK Details >> --------------------------- Эта ошибка связана с деструктором. Если удалить конструкцию "if not Assigned(FMyComponent) then", то ошибка аналогичного типа выдается не при закрытии проекта вцелом, а уже при закрытии самой формы. Подскажите как это можно исправить? Может я что-то в деструкторе неверно прописал? Спасибо всем за помощь. |
Сообщ.
#2
,
|
|
|
Наследники TComponent сами убивают своих вложенных собратьев.
Чтобы избежать такой ошибки, надо делать: FParentComponent := TMyComponent.Create(nil); |
Сообщ.
#3
,
|
|
|
Приведенные конструктор и деструктор просто не нужны.
|
Сообщ.
#4
,
|
|
|
Спасибо. проблема решена.
|
Сообщ.
#5
,
|
|
|
Цитата SkAndriy @ Спасибо. проблема решена. По совету yavfast? Если да, то вы получили новую: утечку памяти. Для того чтобы убедиться в этом в тестововм проекте присвойте глобальной переменной ReportMemoryLeaksOnShutDown значение true. Сделать это удобно например в секции initialization модуля главной формы, а еще лучше в файле проекта сразу после слова begin. Тогда менеджер памяти при выходе из программы уведомит вас с помощью диалогового окошка об имеющихся утечках если таковые на самом деле есть. Если нет, то никакого окошка не уидите. |
Сообщ.
#6
,
|
|
|
Сделал как Вы советовали
В public { Public declarations } end; var Form1: TForm1; ReportMemoryLeaksOnShutDown : Boolean; implementation {$R *.dfm} объявил глобальную переменную в модуле проекта ее после begin прописал: program Project1; uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin ReportMemoryLeaksOnShutDown := True; Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Никаких сообщений не получил. Все правильно прописал? Спасибо |
Сообщ.
#7
,
|
|
|
Цитата SkAndriy @ объявил глобальную переменную Нет, объявлять ничего не надо было: она уже объявлена в модуле System. Можете даже это уточнить в коде явно. program Project1; uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin System.ReportMemoryLeaksOnShutdown := true; Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end. Ваша вновь объявленная переменная конечно скрыла оригинальную, которую анализирует менеджер памяти. Соответственно никаких сообщений вы таким образом не получите даже при утечках. Объявление из модуля формы лучше убрать даже при указании модуля явно. |
Сообщ.
#8
,
|
|
|
И как разобраться в полученном перечне? По компоненту (его типам) от 23 до 84 байт. Что это означает? И как тогда поступить с моей проблемой, чобы не было утечки памяти?
|
Сообщ.
#9
,
|
|
|
Цитата SkAndriy @ И как разобраться в полученном перечне? Ого, так там еще и целый перечень! Из того, что показано в первом посте должно быть только TMyComponent x количество набросанный TMyChildComponent'ов c переустановленным свойством ParentComponent. Лечится это удалением приведенных конструктора и деструктора (если это полное их содержимое и нет ничего что вы не стали здесь приводить как не относящееся к проблеме), так они только вредят. Если что-то еще есть в перечне, так по имени типа ищите где создаются соответствующие объекты и не освобождаются. |
Сообщ.
#10
,
|
|
|
Для справки две трети этого списка - это модули бренда программирования Делфи 2010. А мои модули имеют скромные несколько десятков байт всего.
Если Вы пишете, что конструкторы и деструкторы не нужны, то как же тогда создавать компоненты. Это что-то новое. Поясните свою мысль, может действительно я отстал от реальной жизни и компоненты уже создаются без конструкторов и деструкторов. Спасибо. |
Сообщ.
#11
,
|
|
|
Цитата SkAndriy @ Если Вы пишете, что конструкторы и деструкторы не нужны, то ка же тогда создавать компоненты. Это что-то новое. Поясните сволю мысль может действительно я отстал от реальной жизни и компоненты уже создаются без конструкторов и деструкторов. Ничего нового здесь нет. Конструктор и деструктор будут использованы унаследованные и совершенно нет никакой необходимости их заменять новыми с единственным полезным действием - вызовом унаследованных версий. |
Сообщ.
#12
,
|
|
|
Цитата SkAndriy @ Если Вы пишете, что конструкторы и деструкторы не нужны, то ка же тогда создавать компоненты. Это что-то новое Не нужно переопределять конструкторы\деструкторы, если они не выполняют никаких полезных действий по сравнению с наследуемыми (inherited). Зачем ты в #1 в конструкторе создаешь некий безымянный FParentComponent, который затем может "10 раз" переустановиться в инспекторе - совершенно не понятно. Аналогично и в деструкторе незачем удалять дочерний компонент, т.к. он сам удалится в inherited Destroy |
Сообщ.
#13
,
|
|
|
Спасибо, попробую.
|
Сообщ.
#14
,
|
|
|
PS:
Цитата leo @ в деструкторе незачем удалять дочерний компонент, т.к. он сам удалится в inherited Destroy А если это не дочерний, а некий "родительский", назначаемый в инспекторе, то тем более - нельзя удалять то, "что тебе не принадлежит" |