I had another error in my application caused by careless use of Delphi interfaces. When I pass an interface to a procedure that ignores this argument, the instance is never freed. See the following simple example:
ITest = interface procedure Test; end; Tester = class(TInterfacedObject, ITest) public procedure Test; end; Base = class public procedure UseTestOrNot(test : ITest); virtual; abstract; end; A = class(Base) public procedure UseTestOrNot(test : ITest); override; end; B = class(Base) public procedure UseTestOrNot(test : ITest); override; end; { A } procedure A.UseTestOrNot(test: ITest); begin test.Test(); end; { B } procedure B.UseTestOrNot(test: ITest); begin WriteLn('No test here'); end; // -------- Test --------------------------------------- var list : TObjectList<Base>; x : Base; t : ITest; begin ReportMemoryLeaksOnShutdown := true; list := TObjectList<Base>.Create; list.Add(A.Create); list.Add(B.Create); // 1 x Tester leak for each B in list: for x in list do x.UseTestOrNot(Tester.Create); // this is ok for x in list do begin t := Tester.Create; x.UseTestOrNot(t); end; list.Free; end.
Could you explain what went wrong with the watch counter? Can you give any recommendation / guide (for example, βNever create a conjugate instance inside a function call [unless you know what is going on insideβ).
The best solution I can come up with for this example is to write a template method in the Base class that saves the passed test instance and calls the abstract DoUseTestOrNot method.
EDIT Delphi 2010
interface delphi delphi-2010
hansmaad
source share