У меня следующая структура класса.
TObjectA = class
...
end;
TObjectB = class
private
FDependencyObjectA
public
constructor Create(const DependencyA: TObjectA);
destructor Destroy; override;
end;
{ TObjectB }
constructor TObjectB.Create(const DependencyA: TObjectA);
begin
FDependencyObjectA := DependencyA;
end;
destructor TObjectB.Destroy;
begin
FDependencyObjectA.Free;
FDependencyObjectA := nil;
inherited;
end;
Я пытаюсь найти решение для работы с этими двумя вариантами использования.
// Use cases
// First case
// Works with Free on Destroyer
// Does not work without Free on Destroyer
procedure TForm1.Button1Click(Sender: TObject);
var
ObjectB: TObjectB;
begin
ObjectB := TObjectB.Create(TObjectA.Create);
try
...
finally
ObjectB.Free;
end;
end;
// Second case
// Does not work with Free on Destroyer
// Works without Free on Destroyer
procedure TForm1.Button1Click(Sender: TObject);
var
ObjectA: TObjectA;
ObjectB: TObjectB;
begin
ObjectA := TObjectA.Create;
ObjectB := TObjectB.Create(ObjectA);
try
...
finally
// Depending on the implementation of the Destroyer or the this finally
// Can raise Access Violation, Invalid Pointer or Memory Leak
ObjectB.Free;
ObjectA.Free;
end;
end;
Одним из решений будет проверкачто ObjectA уже свободен от памяти.Но я не знаю проверки только тогда, когда объект свободен, я знаю проверки того, когда объект нулевой.
// Third case (Trying for a solution)
procedure TForm1.Button1Click(Sender: TObject);
var
ObjectA: TObjectA;
ObjectB: TObjectB;
begin
ObjectA := TObjectA.Create;
ObjectB := TObjectB.Create(ObjectA);
try
...
finally
ObjectB.Free;
// It would work fine if Assigned returned false, but always returns true
if Assigned(ObjectA) then // or ObjectA <> nil
ObjectA.Free;
// If I use just assign nil instead of Free, compile throws a hint
// ObjectA := nil;
// H2077 Value assigned to 'Your_Variable' never used
end;
end;
Другим решением будет внедрение зависимости с использованием зарезервированного слова var.Но сначала я хочу оценить другие возможности.
В Delphi есть ли способ проверить, является ли объект просто свободным и не только нулевым?
Или есть ли обходной путь для работы с первымдва варианта использования, без ошибок Access Violation, Invalid Pointer, Memory Leak или Compile Hints?
Я не просто хотел принять только один вариант использования, или мне приходилось постоянно проверять разрушитель объекта, чтобы знать, как реализоватьновая функция / процедура.Это плохо для повседневных реализаций или когда в проект вступает новый разработчик.Мы должны были бы объяснить все эти маленькие правила, а также постоянно проверять правильность реализаций.
Редактировать:
Я знаю, что в Delphi есть ARC для интерфейсов, ноне все объекты реализуют интерфейс.
Для подсказок есть директива компиляции {$ Hints Off}, но в любом случае добавление этой директивы не очень эффективно.