2012-08-04 11 views
7

I tienen una unidad que tiene una variable de TComponent, I crear este componente en la inicialización de la unidad como siguiente:¿Puedo usar .Create (cero) en lugar de .Create (Aplicación)

var 
    XComp: TComponent; 
. 
. 
. 
. 

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

después de instalar la unidad cuando cierro Delphi me da un mensaje de error Violación de Acceso (EAccessViolation)

pero cuando he cambiado de creador a ser las siguientes

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

todo ha ido bien ... me gustaría saber la diferencia? y que es lo mejor?

nota: el error solo aparece al cerrar el delphi (significa en tiempo de diseño).

Gracias.

+0

Aquí está ['uno de los follow ups'] (http://stackoverflow.com/q/5420260/960757). – TLama

+6

Está creando 'XCom' en la sección' initialization'. ¿También tienes una sección de 'finalización' que la libera? –

Respuesta

2

Básicamente tanto están permitidos y no debería dar lugar a un AV, incluso si tiene un código como éste:

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

Esto se debe a un componente correctamente codificado se borrará de la lista de componentes de su propietario cuando está siendo destruido.

Creo que el problema aquí podría ser que el componente ya fue liberado por el objeto de la aplicación y más adelante algún código intenta acceder a él. Tal vez haya una sección de finalización en tu código, ¿o sí? O puede que tenga objetos mixtos e interfaces y el recuento de referencias lo consiguió.

Para depurar su problema, puede ejecutar el IDE en el depurador configurando la "aplicación de host" de su paquete en Delphi (C: \ Archivos de programa \\ BDS \\ Bin \ bds.exe). y establece un punto de interrupción en el destructor de tu componente. De esta forma descubrirá dónde se libera y también dónde se produce el AV.

13

Cuando se utiliza

XCom := TComponent.Create(Application); 

que hacer una solicitud al propietario de XCom. Cuando la aplicación finalice, se encargará de destruir XCom, ya que es el propietario.

Al hacer

XCom := TComponent.Create(nil); 

nadie es dueño de XCom y hay que liberar a usted mismo cuando la aplicación termina.

Probablemente haya recibido la excepción porque manualmente liberó XCom y luego la Aplicación intentó liberar XCom también.

+5

+1. Como guía general: use 'nil' cuando liberará el objeto usted mismo, y' Application' si no lo está y quiere que se lo limpien o si existe la posibilidad de que no lo pueda liberar tú mismo. –

+1

@birger: si el componente está codificado correctamente, se eliminará de la lista de componentes del propietario (en este caso, la Aplicación) cuando se libere. Entonces, en teoría, un AV no debería suceder. Creo que podría ser al revés: el componente ya fue liberado por la aplicación y el programa intentó acceder a él más tarde. Si interpreto correctamente la pregunta, este es un componente en un paquete designtime y el AV se produce en Delphi IDE, por lo que es un poco más complejo. – dummzeuch