2012-08-04 15 views
7

Mam urządzenie, które ma zmienną TComponent, tworzę ten składnik inicjalizacji urządzenia jak następuje:mogę używać .Create (zero) zamiast .Create (Application)

var 
    XComp: TComponent; 
. 
. 
. 
. 

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

po zainstalowaniu jednostka gdy zamknę Delphi wyskakuje mi komunikat o błędzie naruszenia zasad dostępu (EAccessViolation)

ale kiedy zmieniłem twórcę się następująco

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

wszystko poszło dobrze ... ja chciałbyś poznać różnicę? i co jest lepsze?

uwaga: błąd pojawia się tylko przy zamykaniu delphi (oznacza w czasie projektowania).

Dzięki.

+0

Oto jeden z następujących przykładów: (http://stackoverflow.com/q/5420260/960757). – TLama

+6

Tworzysz 'XCom' w sekcji' inicjalizacja'. Czy masz również sekcję "finalizacji", która ją zwalnia? –

Odpowiedz

2

Zasadniczo oba są dozwolone i nie powinno skutkować AV, nawet jeśli masz kodu:

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

To dlatego, że prawidłowo zakodowany składnik usunie się z listy składników swojego właściciela, gdy jest zniszczony.

Myślę, że problemem może być to, że składnik został już zwolniony przez obiekt aplikacji, a później jakiś kod próbuje uzyskać do niego dostęp. Może w twoim kodzie jest sfinalizowana sekcja, która to robi? Lub możesz mieć mieszane obiekty i interfejsy, a liczenie odwołań zostało osiągnięte.

Aby usunąć problem, można uruchomić środowisko IDE w debugerze, ustawiając "aplikację hosta" pakietu na Delphi (C: \ Program Files \\ BDS \\ Bin \ bds.exe). i ustaw punkt przerwania w destruktorze komponentu. W ten sposób dowiesz się, gdzie jest on uwalniany, a także gdzie pojawia się AV.

13

Podczas korzystania

XCom := TComponent.Create(Application); 

dokonać Zastosowanie właściciel XCOM. Gdy aplikacja się zakończy, zajmie się zniszczeniem XCom, ponieważ jest właścicielem.

Kiedy robisz

XCom := TComponent.Create(nil); 

nikt nie jest właścicielem XCOM i trzeba go uwolnić, gdy aplikacja kończy.

Prawdopodobnie dostałeś wyjątek, ponieważ ręcznie zwolniłeś XCom, a następnie aplikacja próbowała zwolnić XCom.

+5

+1. Jako ogólny przewodnik: użyj 'nil', gdy będziesz uwalniał obiekt samemu, a' Application', jeśli nie jesteś i chcesz, żeby to zostało oczyszczone lub jeśli istnieje szansa, że ​​nie będziesz mógł go uwolnić siebie. –

+1

@birger: jeśli komponent zostanie poprawnie zakodowany, usunie się z listy komponentów właściciela (w tym przypadku: aplikacji), gdy jest on wolny. Więc teoretycznie AV nie powinno się zdarzyć. Myślę, że może być odwrotnie: komponent został już zwolniony przez aplikację, a program próbował później uzyskać do niego dostęp. Jeśli poprawnie zinterpretuję pytanie, jest to komponent w pakiecie designtime, a AV pojawia się w IDE Delphi, więc jest to nieco bardziej skomplikowane. – dummzeuch