2012-08-04 10 views
7

Ich habe eine Einheit, die eine Variable von TComponent hat, erzeuge ich diese Komponente auf Initialisierung der Einheit wie folgt vor:Kann ich .Create (Nil) statt .Create (Anwendung)

var 
    XComp: TComponent; 
. 
. 
. 
. 

initialization 
begin 
    XCom := TComponent.Create(Application); 
end; 

nach der Installation das Gerät, wenn ich in der Nähe Delphi es mir eine Fehlermeldung Zugriffsverletzung (EAccessViolation)

aber wenn ich änderte meine Schöpfer zu sein, wie folgend

initialization 
begin 
    XCom := TComponent.Create(nil); 
end; 

alles ging gut ... I gibt möchte den Unterschied wissen? und was ist besser?

Hinweis: Der Fehler tritt nur beim Schließen des Delphi auf (bedeutet zur Entwurfszeit).

Danke.

+0

Hier ist ['eins der Follow-ups'] (http://stackoverflow.com/q/5420260/960757). – TLama

+6

Sie erstellen 'XCom' im Abschnitt' initialization'. Haben Sie auch eine 'Finalisierung'-Sektion, die es freigibt? –

Antwort

2

grundsätzlich beide sind erlaubt und es sollte in einem AV selbst nicht führen, wenn Sie Code wie dieses:

MyComp := TMyComp.Create(Application); 
try 
    {...} 
finally 
    MyComp.Free; 
end; 

Dies liegt daran, eine korrekt codierte Komponente selbst Komponenten Liste der von seinem Besitzer entfernen wird, wenn es sein zerstört.

Ich denke, das Problem hier könnte sein, dass die Komponente bereits durch das Anwendungsobjekt freigegeben wurde und später versucht einige Code auf es zuzugreifen. Vielleicht gibt es einen Abschluss in Ihrem Code, oder? Oder Sie haben möglicherweise gemischte Objekte und Schnittstellen und Referenzzählung bekam Sie.

Um Ihr Problem zu debuggen, können Sie die IDE im Debugger ausführen, indem Sie die "Host-Anwendung" Ihres Pakets auf Delphi (C: \ Programme \\ BDS \\ Bin \ bd.exe) setzen. und legen Sie im Destruktor Ihrer Komponente einen Haltepunkt fest. Auf diese Weise erfahren Sie, wo es freigegeben wird und wo das AV auftritt.

13

Wenn Sie

verwenden
XCom := TComponent.Create(Application); 

Sie Anwendung machen die Besitzer der XCOM. Wenn die Anwendung beendet wird, wird XCom zerstört, da es der Besitzer ist.

Wenn Sie das tun

XCom := TComponent.Create(nil); 

niemand Besitzer XCom und Sie haben es sich zu befreien, wenn die Anwendung beendet wird.

Sie haben wahrscheinlich die Ausnahme erhalten, weil Sie XCom manuell freigegeben haben und dann die Anwendung versucht hat, XCom ebenfalls zu befreien.

+5

+1. Als allgemeine Anleitung: Verwenden Sie "nil", wenn Sie das Objekt selbst befreien, und "Application", wenn Sie nicht sind und Sie möchten, dass es für Sie aufgeräumt wird oder wenn es eine Chance gibt, dass Sie es nicht befreien können dich selber. –

+1

@Birger: Wenn die Komponente ordnungsgemäß codiert ist, wird sie beim Freigeben aus der Komponentenliste des Besitzers (in diesem Fall: Anwendung) entfernt. Also sollte theoretisch kein AV passieren. Ich denke, es könnte umgekehrt sein: Die Komponente wurde bereits von der Anwendung freigegeben und das Programm versuchte danach darauf zuzugreifen. Wenn ich die Frage richtig interpretiere, ist dies eine Komponente in einem Designtime-Paket und das AV tritt in der Delphi-IDE auf, also ist das etwas komplexer. – dummzeuch