// *** before: ***
// every interface reference counted, and two objects holding each other
// kept the count above zero forever: neither was ever freed
type
IParent = interface
['{1B4D5E90-3C22-4F18-A7D6-51C08E3A9F42}']
procedure Print;
end;
IChild = interface
['{2A5C6D10-7E31-4A9B-8C22-9D4F60B7E115}']
end;
TParent = class(TInterfacedObject, IParent)
private
FChild: IChild; // the parent holds the child
end;
TChild = class(TInterfacedObject, IChild)
private
FParent: IParent; // and the child holds the parent - a leak
end;
// on Windows the way out was to store the raw object instead of the
// interface, or to nil one of the fields by hand at the right moment
// *** in version 10.1: ***
type
TChild = class(TInterfacedObject, IChild)
private
[weak] FParent: IParent; // does not raise the reference count
public
procedure Report;
end;
procedure TChild.Report;
begin
// when the parent is freed, the compiler sets a weak reference to nil,
// so the check below is honest
if FParent <> nil then
FParent.Print;
end;
// the attribute was available on the mobile compilers before; from 10.1
// it works on Windows too