Сейчас в компиляторе есть, не совсем понятная мне, особенность.
При освобождении интерфейса, сначала вызывается _Release, а уже потом переменная хранящая собственно указатель интерфейса получает значение nil.
Спрашивается - это by design или просто реализация такая?
Тестовый пример ниже.
- Код: Выделить всё
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
type
IIntf = interface
['{2238A7F7-4C08-456B-BEF2-429D8472B4AC}']
end;
TClass2 = class;
{ TClass1 }
TClass1 = class(TInterfacedObject, IIntf)
private
FOwner:TClass2;
FStr:string;
public
constructor Create(Owner:TClass2);
destructor Destroy;override;
end;
{ TClass2 }
TClass2 = class
private
I:IIntf;
public
constructor Create;
destructor Destroy;override;
procedure WriteLn;
end;
{ TClass1 }
constructor TClass1.Create(Owner: TClass2);
begin
inherited Create;
FOwner:=Owner;
end;
destructor TClass1.Destroy;
begin
FOwner.WriteLn;
inherited Destroy;
end;
{ TClass2 }
constructor TClass2.Create;
begin
inherited;
I:=TClass1.Create(Self);
end;
destructor TClass2.Destroy;
begin
I:=nil;
inherited Destroy;
end;
procedure TClass2.WriteLn;
begin
if I <> nil then
System.WriteLn( 'I <> nil' );
end;
var
O2:TClass2;
begin
O2:=TClass2.Create;
O2.Free;
end.
Этот пример выводит 'I <> nil' хотя в момент вызова TClass2.Writeln количество ссылок уже упало до нуля и вызвался деструктор TClass1.