Oder du sorgst dafür, dass die Objekte wissen, wo sie überall referenziert werden und dann selber dafür sorgen diese Referenzen zu entfernen.
Kleines Beispiel dafür ist hier mit einem Visitor gelöst.
Zur Vereinfachung habe ich alle möglichen Prüfungen herausgelassen (Ist Item schon SubItem beim hinzufügen oder ist Item überhaupt SubItem beim Entfernen)
Delphi-Quellcode:
unit uObjects;
interface
uses
Classes, Contnrs;
type
TMyItem =
class
private
FSubItems : TObjectList;
FAnchors : TObjectList;
// Die Visitor-Routinen
procedure AddedToItem( Item : TMyItem );
procedure RemovedFromItem( Item : TMyItem );
public
property SubItems : TObjectList
read FSubItems;
property Anchors : TObjectList
read FAnchors;
// Hinzufügen und entfernen nur über diese Routinen
procedure AddSubItem( Item : TMyItem );
procedure RemSubItem( Item : TMyItem );
constructor Create;
destructor Destroy;
override;
end;
implementation
{ TMyItem }
procedure TMyItem.AddedToItem( Item : TMyItem );
begin
FAnchors.Add( Item );
end;
procedure TMyItem.AddSubItem( Item : TMyItem );
begin
FSubItems.Add( Item );
Item.AddedToItem( Self );
end;
procedure TMyItem.RemovedFromItem( Item : TMyItem );
begin
FAnchors.Remove( Item );
end;
procedure TMyItem.RemSubItem( Item : TMyItem );
begin
FSubItems.Remove( Item );
Item.RemovedFromItem( Self );
end;
constructor TMyItem.Create;
begin
inherited;
FSubItems := TObjectList.Create;
FAnchors := TObjectList.Create;
end;
destructor TMyItem.Destroy;
var
obj : TObject;
begin
// Verbindungen lösen wo man SubItem ist
while FAnchors.Count > 0
do
begin
obj := FAnchors[ 0 ];
if obj
is TMyItem
then
TMyItem( obj ).RemSubItem( Self );
end;
// Verbindungen zu den SubItems lösen
while FSubItems.Count > 0
do
begin
obj := FSubItems[ 0 ];
if obj
is TMyItem
then
RemSubItem( TMyItem( obj ) );
end;
FSubItems.Free;
FAnchors.Free;
inherited;
end;
end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9
dc 90 9d f0 e9 de 13 da 60)