To będzie trochę brudny. Musiałbyś zrobić coś takiego.
type
TOwnerComponent = class(TComponent)
private
FOwnedObject: TObject;
public
constructor Create(Owner: TComponent; OwnedObject: TObject);
destructor Destroy; override;
end;
TOwnedStringList = class(TStringList)
private
FOwner: TOwnerComponent;
public
constructor Create(Owner: TComponent);
destructor Destroy; override;
end;
{ TOwnerComponent }
constructor TOwnerComponent.Create(Owner: TComponent; OwnedObject: TObject);
begin
inherited Create(Owner);
FOwnedObject := OwnedObject;
end;
destructor TOwnerComponent.Destroy;
begin
FOwnedObject.Free;
inherited;
end;
{ TOwnedStringList }
constructor TOwnedStringList.Create(Owner: TComponent);
begin
inherited Create;
if Assigned(Owner) then
FOwner := TOwnerComponent.Create(Owner, Self);
end;
destructor TOwnedStringList.Destroy;
begin
if Assigned(FOwner) and not (csDestroying in FOwner.ComponentState) then
begin
FOwner.FOwnedObject := nil;
FOwner.Free;
end;
inherited;
end;
Zasadniczo utworzyć instancję TOwnerComponent
który jest własnością Owner
które przechodzą do TOwnedStringList.Create
. Kiedy ten Owner
umiera, niszczy on TOwnerComponent
, który z kolei niszczy twoją listę ciągów.
Kod jest odporny na jawne wywołanie Free
na liście ciągów.
+1 Ta sama sztuczka co w przypadku interfejsów w rekordach – jpfollenius
Wygląda obiecująco. Czy konstruktor TOwnerComponent powinien być utworzony z dyrektywą 'reintroduce'? Ponadto, Jak mogę chronić 'TOwnedStringList' przed' sl.Create (zero) 'i jawne' sl.Free'? – ZigiZ
'Utwórz (zero)' jest w porządku. To znaczy, nie ma właściciela, pozwól mi przejąć odpowiedzialność za własność. Lub jeśli tego nie chcesz, wtedy podnieś wyjątek. Wyraźny "Wolny" wymaga nieco więcej myślenia. Niedźwiedź ze mną. –