У меня есть следующий код:ТГогт в Spring4D
Project.dpr
program Project2;
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
Spring.Container,
Vcl.Forms,
uRegistrations in '..\Memory leak II\uRegistrations.pas',
Unit3 in 'Unit3.pas' {MainForm},
Unit4 in 'Unit4.pas' {SecondaryForm},
Unit5 in 'Unit5.pas';
{$R *.res}
begin
RegisterTypes(GlobalContainer);
Application.Initialize;
Application.MainFormOnTaskbar := True;
// MainForm:=TMainForm.Create(nil);
Application.CreateForm(TMainForm, MainForm);
MainForm.SecondaryForm := Globalcontainer.Resolve<ISecondaryForm>;
Application.Run;
end.
uRegistrations.pas, который регистрирует интерфейса
unit uRegistrations;
interface
uses
Spring.Container;
procedure RegisterTypes(Container: TContainer);
implementation
uses
Unit5,
Unit4;
procedure RegisterTypes(Container: TContainer);
begin
container.RegisterType<ISecondaryForm, TSecondaryForm>.DelegateTo(
function: TSecondaryForm
begin
result := TSecondaryForm.Create(nil);
end);
Container.Build;
end;
end.
Unit3.pas удерживая основную форму
unit Unit3;
interface
uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Unit5,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs;
type
TMainForm = class(TForm)
private
{ Private declarations }
FSecondaryForm: ISecondaryForm;
public
{ Public declarations }
property SecondaryForm: ISecondaryForm read FSecondaryForm write FSecondaryForm;
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
end.
Unit4.pas с вторичной формой
unit Unit4;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
unit5,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TSecondaryForm = class(TForm, ISecondaryForm)
private
{ Private declarations }
public
{ Public declarations }
end;
//var
// SecondaryForm: TSecondaryForm;
implementation
{$R *.dfm}
end.
и, наконец, Unit5.pas с декларацией интерфейса
{$M+}
unit Unit5;
interface
type
ISecondaryForm=interface
['{62D63E9A-A3AD-435B-8938-9528E70D78B1}']
end;
implementation
end.
Он собирает и работает регулярно, но когда я закрыть приложение, у меня есть три утечки памяти.
число распределения: 8482 программа Время: 721 Тип мс: Кисть Ручка ручка: $ 461027f5 стиль: BS_SOLID цвет: $ f0f0f0
число распределения: 8318 программа Время: 697 Тип мс: TSecondaryForm адрес: $ d51ac64 размер: 924 права доступа: чтение/запись
номер распределения: программа 8267 до времени: Тип 693 мс: шрифт ручка ручка: $ 1d0a28f1 лицо: Tahoma высота: -11
Почему это происходит и как я могу его решить?
EDIT
После ответа, я реализовал следующие решения (комментарии выделить ошибки, которые я получил:
procedure RegisterTypes(Container: TContainer);
begin
container.RegisterType<ISecondaryForm, TSecondaryForm>.DelegateTo(
function: TSecondaryForm
begin
result := TSecondaryForm.Create(nil);
result.Owner:=Application.MainForm;//cannot assign to a read-only property
result.Parent:=Application; //incompatible types
result.Parent:=application.MainForm;//memory leak
end);
Container.Build;
end;
Я также попытался изменить OnClose метод TSecondaryForm в следующем путь:.
procedure TSecondaryForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree; //memory leak
end;
, но я получил утечку памяти
Что я делаю неправильно со всей техникой выше?
В конце концов, я только что сделал эти два метода _AddRef и _Release управлять подсчетом ссылок, как предложено в комментариях, и у меня нет больше утечек памяти.
TSecondaryForm = class(TForm, ISecondaryForm)
private
{ Private declarations }
protected
FRefCount: Integer;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
{ Public declarations }
end;
function TSecondaryForm._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TSecondaryForm._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result=0 then
self.Free;
end
посмотрите http://stackoverflow.com/questions/20386734/will-an-interface-implementing-form-free-itself-when-there-are-no-more-reference и http: // stackoverflow .com/questions/769329/bypassing-disabling-delphis-reference-counting-for-interfaces – RBA
Передайте владельца в конструкторе, а не в nil –