Changes in new versions / Delphi 10.1 Berlin

// *** before: ***
// to keep a reference without counting it, people stored a Pointer and
// cast it back on every use - the compiler could not help at all
type
  TObserver = class(TInterfacedObject)
  private
    FOwner: Pointer;               // really an ISubject
    function GetOwner: ISubject;
  end;

function TObserver.GetOwner: ISubject;
begin
  Result := ISubject(FOwner);      // nothing checks that this is valid
end;

// *** in version 10.1: ***
type
  TObserver = class(TInterfacedObject)
  private
    [unsafe] FOwner: ISubject;     // typed, but the count is untouched
  end;

var
  [unsafe] Ref: ISubject;
begin
  // [unsafe] costs nothing at run time: it is a plain pointer with the
  // right type. Nobody sets it to nil when the object dies, so it is for
  // references whose lifetime you already control
  //
  // [weak] is the safe half of the pair: it is tracked, and it becomes
  // nil by itself. [unsafe] is the fast half, and it is on you
end;