Изменения в новых версиях / Delphi 10.1 Berlin

// *** 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