Autor Beitrag
dirkil2
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130



BeitragVerfasst: So 31.07.05 22:21 
Ich habe in meinem Programm ein Problem, wenn ich Application.Terminate aufrufe, weil ich eine EAccessViolation bekomme. Ich meine auch zu wissen, warum es passiert, aber ich weiß keine Abhilfe. Vielleicht habt ihr ja eine Idee.

Ich habe ein DataModule für meine Datenbank. Ich verwende Firebird mit FIBPlus Komponenten. In dem DataModule öffne ich im OnCreate meine Datenbank und im OnDestroy schließe ich sie.

In meiner Applikation ist das Erste, was gemacht wird, das Erzeugen des DataModules, da ich die Datenbank gleich zu Anfang benötige. Wenn ich jetzt in meiner Applikation Application.Terminate aufrufe (z.B. wenn ein Nutzer den falschen Registrierungsschlüssel eingegeben hat), dann wird wohl mein DataModule destruiert, BEVOR alle anderen Forms destruiert werden. In diesen Forms wird im Destroy aber noch auf die Datenbank zugegriffen. Da diese aber nicht mehr existiert, knallt's.

Wie kann ich sicherstellen, dass mein DataModule als allerletztes destruiert wird?
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Mo 01.08.05 16:55 
Für Objekte, die ich von vielen verschiedenen Programmteilen aus brauche und die nur einmal vorhanden sein sollen, verwende ich normalerweise Singletons. Die werden erzeugt, wenn man das erste mal auf Sie zugreift und existieren bis zum Programmende. In Delphi kann man das z.B. folgendermassen realisieren:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
interface

type
  TMeinDatenmodul = class(TDataModule)
  ...
  public
    class function Shared(): TMeinDatenmodul;
  end;

implementation

var
  GMeinDatenmodul : TMeinDatenmodul; 

class function TMeinDatenmodul.Shared() : TMeinDatenmodul;
begin
  if not Assigned(GMeinDatenmodul) then
  begin
    GMeinDatenmodul := TMeinDatenmodul.Create(nil);
  end;
  Result := GMeinDatenmodul;
end;

...

initialization
  GMeinDatenmodul := nil;
finalization
  FreeAndNil(GMeinDatenmodul);
end.


Verwenden kannst du das Ding dann mit

ausblenden Delphi-Quelltext
1:
TMeinDatenmodul.Shared.ProzedurXY;					


Beim ersten Aufruf von TMeinDatenmodul.Shared wird das Datenmodul erzeugt, danach wird immer das erzeugte Datenmodul zurückgegeben. Bei Programmende wird
das Datenmodul durch den finalization-Teil der Unit freigegeben. Delphi sorgt dafür, das finalization-Abschnitte in der richtigen Reihenfolge aufgerufen werden.

Stefan