One of the issues I've encountered recently is code like this:

type
  ISomeIntf = interface procedure SomeMethod; end;
  TSomeClass = class(TInterfacedObject, ISomeIntf)
  private
    FValue: Integer;
    FSomeValue: string;
  public
    constructor Create;
    procedure SomeMethod;
  end;

var
  SomeClass: TSomeClass;

procedure DoSomething(ASomeIntf: ISomeIntf);
begin
  ASomeIntf.SomeMethod;
end;

procedure Setup;
begin
  SomeClass := TSomeClass.Create;
end;

procedure InAnotherRoutine;
begin
  DoSomething(SomeClass);
end;

procedure DoAnotherThing;
begin
  SomeClass.SomeMethod; // that references Self
end;

{ TSomeClass }

constructor TSomeClass.Create;
begin
  FValue := 12345;
  FSomeValue := 'Some important stuff';
end;

procedure TSomeClass.SomeMethod;
begin
  WriteLn(FValue);
  WriteLn(FSomeValue);
end;

begin
  Setup;
  InAnotherRoutine;
  DoAnotherThing;
  InAnotherRoutine;
end.

What happens when the call to DoSomething in AnotherRoutine finishes, and a call is made to DoAnotherThing, which calls SomeMethod? Copy and paste the above code into a new console program, and find out by running it!