Hallo zusammen
Ich habe ein bisher einwandfrei laufendes Observerpattern das mir nun nicht mehr wie gewollt will.
Sobald ich die Anwendung schliesse wird nach allen Methoden, also auch nach der Methode Application.Run die
Exception Zugriffsverletzung bei Adresse xy geworfen.
Den Fehler habe ich wie folgt evaluiert:
Das MainForm, ebenfalls ein Objekt, trägt sich beim Observer ein. Funktioniert gut, solange dieses Formular von TForm abgeleitet wird. Sobald eine Ableitung von einem eigenen Formular existiert, stirbt Delphi beim Beenden (sofern er natürlich beim Observer registriert wurde).
Im Anhang einige Codefragmente.
Delphi-Quellcode:
IServerState = interface( IInterface )
['{C5D0851E-E9CD-422B-8E34-BA2C8E53E729}']
procedure ServerStatusChanged( _state: Boolean );
end;
//TFormMain = class( TForm, IServerState ) -> Funktioniert
TFormMain = class( TFormBase, IServerState )
procedure FormCreate( _sender: TObject );
procedure FormClose( _sender: TObject; var _action: TCloseAction );
procedure ServerStatusChanged( _state: Boolean );
end;
{------------------------------------------------ TFormMain }
procedure TFormMain.FormCreate( _sender: TObject );
begin
Inherited;
GetSource.RegisterObserver( Self ); //Registriere sich selbst. GetSource ist Singleton
end {FormCreate};
procedure TFormMain.FormClose( _sender: TObject; var _action: TCloseAction );
begin
GetSource.RemoveObserver( Self );
inherited;
end;
procedure TFormMain.ServerStatusChanged( _state: Boolean );
begin
//Wird benachrichtigt und tut was
end;
{------------------------------------------------ TFormBase }
TFormBase = class( TForm )
BevelTop: TBevel;
ImageBackground: TImage;
ImageHead: TImage;
LabelTitel: TLabel;
ImageListEdit: TImageList;
procedure FormCreate( _sender: TObject );
procedure FormClose( _sender: TObject; var _action: TCloseAction );
end;
(*
In FormCreate und FormClose werden Registryeinträge getätigt. Inherited wird bei beiden aufgerufen
*)
{------------------------------------------------ TSource }
TSource = class( TInterfacedObject )
private
FObservers: TInterfaceList;
public
procedure RegisterObserver( _obs: IServerState );
procedure RemoveObserver( _obs: IServerState );
end;
procedure TSource.RegisterObserver( _obs: IServerState );
begin
if not Assigned( FObservers ) then begin
FObservers:= TInterfaceList.Create;
end;
FObservers.Add( _obs );
end {RegisterObserver};
procedure TSource.RemoveObserver( _obs: IServerState );
begin
if Assigned( FObservers ) then begin
FObservers.Remove( _obs );
if FObservers.Count = 0 then begin
FObservers:= nil;
end;
end;
end {RemoveObserver};
Herzlichen Dank