Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-01-2012
Avatar de Red_Leon
Red_Leon Red_Leon is offline
Miembro
 
Registrado: oct 2007
Ubicación: Castilla la Mancha
Posts: 27
Poder: 0
Red_Leon Va por buen camino
Problema con Interfaces

Buenas compañeros,

Tengo un pequeto problema con las interfaces en Delphi 7/XE, aver si me pudieras echar una mano ya que no sé el porque puede estar pasando.

Tengo declarada una interface definida tal que así:

Código Delphi [-]
 IEjemplo=Interface
    ['{52E6DD18-D15B-46D6-AED1-F146A438C3AC}']
    { Public declarations }
    procedure proX;
  end;

Tengo varias clases que implementan este interface tal que asi:

Código Delphi [-]
Unit1

TClase1=class(TInterfacedObject, IEjemplo)
  public
    procedure proX;
  private
    ...
  end;

var
  ejemplo1:TClase1;

implementation

....

Unit2

TClase2=class(TInterfacedObject, IEjemplo)
  public
    procedure proX;
  private
    ...
  end;

var
  ejemplo2:TClase2;

....

Hasta aqui todo bien, con su teoria y todo.

Bien, pues me he creado un controler el cual dependiendo de la ocasión utilizará un interface o otro. El controller en resumidas cuentas es tal que así:

Código Delphi [-]

type

  TControllerE=class
  public
     ....
     constructor Create;
     procedure establecerInterface(index:Integer);
     ....
  private
     ....
    interface:IEjemplo;
     ....
     procedure llamarInterface;
     ....
  end;

implementation
   constructor TControllerE.Create;
   begin
      ejemplo1:=TClase1.Create;
      ejemplo2:=TClase2.Create;
      self.interface:=nil;
   end; 

   procedure TControllerE.establecerInterface(index:Integer);
   begin
      if (index=1) then
        self.interface:=ejemplo1
      else if (index=2) then
        self.interface:=ejemplo2
      else
        self.interface:=nil
   end;

   procedure TControllerE.llamarInterface;
   begin
      if (self.interface <> nil)  then self.interface.proX;  
   end;

Hasta aqui creo que actuo correctamente.

Y es resumidas cuentas se hace esto, pongamos en un botón;

Código Delphi [-]
  controlerE:=TControllerE.Create;
  controlerE.establecerInterface(1);
  controlerE.establecerInterface(2); 
  controlerE.establecerInterface(1);

El problema es que al restablecer el interface 1 me salta una Excepcion: ... EAccessViolation with the Message 'Access violation at Adress XXXXXX'...

¿Que estoy haciendo mal? En ningun momento libero los objetos ejemplo1, ejemplo2. Es más en debbug compruebo que tiene valor, pero al igualarlo a la variable interface es donde salta.

He estado mirando ejemplos y demás y no veo ninguno en el cual utilice los interfaces de esta manera.

¿Puede ser que le este dando un mal uso a los interface en Delphi?

Muchas gracias por adelantado.
Responder Con Cita
  #2  
Antiguo 18-01-2012
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Poder: 16
LoPiTaL Va por buen camino
Hola,
El problema es que los objetos que implementan interfaces llevan un conteo del nº de referencias que apuntan a ellos (mira en detalle la implementación de TInterfacedObject, los métodos _AddRef y _Release). Cuando el nº de referencias es 0, entonces se autodestruyen.

Cuando asignas self.interface:=ejemplo1, entonces ejemplo1.RefCount vale 1.
Cuando asignas self.interface:=ejemplo2, entonces ejemplo1.RefCount pasa a valer 0, autodestruyéndote ejemplo1.
Cuando vuelves a asignar self.interface:=ejemplo1, entonces ejemplo2.RefCount pasa a valer 0, autodestruyéndote ejemplo2, y interface pasa a referenciar a un sitio en el que no hay nada (se autodestruyó anteriormente) y de ahi la excepción.

Para el ejemplo que estás dando, yo usaría lo mismo, pero en lugar de derivar interfaces, derivaría de una clase común, del estilo:

TClasePadre=class
procedure proX; virtual; abstract;
end;

y tu puntero en lugar de ser de tipo IEjemplo, sería de tipo TClasePadre.

Un saludo,
LoPiTaL
Responder Con Cita
  #3  
Antiguo 18-01-2012
Avatar de Red_Leon
Red_Leon Red_Leon is offline
Miembro
 
Registrado: oct 2007
Ubicación: Castilla la Mancha
Posts: 27
Poder: 0
Red_Leon Va por buen camino
Toda la razón LoPiTaL!

Lo que me ha llamado la atención es que si hacia:
controlerE.establecerInterface(1);
controlerE.establecerInterface(2);
controlerE.establecerInterface(1);



Saltaba la excepción. Pero si lo hacia al reves:
controlerE.establecerInterface(2);
controlerE.establecerInterface(1);
controlerE.establecerInterface(2);



No! ¿Por que?....Porque ejemplo2 tenia variables dentro y ejemplo1 no.

Por lo cual interpreto con tu explicación que al existir una reserva de memoria del objeto no se libera como bien dices.

Seguire tu consejo o con el case que tenia preparado.

De vez en cuando por intentar optimizar código la que te buscas .
Muchas gracias!
Responder Con Cita
  #4  
Antiguo 18-01-2012
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Poder: 16
LoPiTaL Va por buen camino
Cita:
Empezado por Red_Leon Ver Mensaje
No! ¿Por que?....Porque ejemplo2 tenia variables dentro y ejemplo1 no.

Por lo cual interpreto con tu explicación que al existir una reserva de memoria del objeto no se libera como bien dices.
Al hacerlo al revés también libera el objeto de ejemplo2, independientemente de las variables que tenga la clase. Si no da error ahí, es casualidad.
Si tienes ganas, prueba a usar FastMM con la opción para detectar lectura de interfaces liberadas, y verás como sí te detecta un problema (saltará una excepción).
O más sencillo, prueba a hacer, tras establecer la interfaz 2 por 2ª vez, a llamar al método proX ese. Y te dará error o devolverá datos que no son coherentes.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Problema con las interfaces gráficas skatevil Gráficos 4 04-02-2008 16:55:52
interfaces luislat40 Varios 2 23-10-2007 03:47:23
Interfaces... OscarG OOP 9 14-10-2005 13:26:57
Interfaces de XML vhr Providers 2 26-08-2005 17:22:06
Interfaces Legolas Varios 14 17-11-2003 14:39:07


La franja horaria es GMT +2. Ahora son las 23:23:04.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi