FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Como libero una forma que llame con un show
Tengo un problema que posiblemente sea muy basico pero es que normalmente muestro las formas de forma modal y al final las elimino con un free, pero estoy programando una aplicacion en la cual necesito crear y mostrar las formas no-modales para que el usuario pueda cambiar de una forma a otra, el problema es que la aplicacion va a estar creando y eliminando las formas de forma dinamica por lo que me interesa saber como las mando eliminar ya que al ponerle el free y al mandarlas crear, me toma como si ya estuvieran creadas y se salta a otras partes del codigo
Este es el codigo con el que creo la forma, y pues ya en el OnClose de la forma que mande llamar esta este codigo:
la cuestion es que cuando se intenta volver a crear ya no entra al Create toma como si ya estuviera creada y se salta al Show y me manda este error: "Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00000000. Read of address 0000000000. Process stopped. Use Step or Run to continue." quiero suponer que es porque no libera la forma completamente y no vuelve a crear una nueva y cuando cae al Show o donde le mando las corrdenadas no hay nada creado, o no se, ahi si alguien me puede echar la mano se los agradezco, se que la opcion mas facil seria ocultar la forma, pero se van a crear muchas formas por lo que si necesito estarlas creando y destruyendo, de antemano gracias. |
#2
|
||||
|
||||
No es que no libere completamente el formulario. Recuerda que una variable de tipo objeto es en realidad un puntero al objeto. Al usar Free se libera la memoria asignada al objeto pero el puntero sigue apuntando a una porción de memoria que ya no es válida. En algún momento tienes que volver a poner el puntero en nil. Una comparación como
if Assigned (FMenuPrecios) then realmente no verifica si el objeto existe o no, únicamente verifica si la referencia a dicho objeto (la variable) es nil o no. Es decir, la comparación es equivalente a: if FMenuPrecios <> nil then En el evento OnClose podrías intentar poner FMenuPrecios := nil; // Saludos |
#3
|
||||
|
||||
A ver qué tal parece esta opción
Hola,
Donde dije: "Yo lo he podido solucionar de esta manera, que, probablemente no sea la mejor. En todo caso a ver qué te parece la solución y la explicación que le doy al error que te encuentras." Debí decir: Vale. Hasta aquí el típico párrafo en que uno se lava las manos antes de tratar de indicar la solución de un problema, comprendiendo que lo que va a decir puede estar equivocado (como así ha resultado). Donde dije: "Primero el error. Este aparece, si no estoy equivocado, porque, efectivamente, al cerrar una vez la "forma" secundaria liberas de la memoria cualquier referencia de esta." Debí decir: Hasta aquí más o menos estoy de acuerdo con lo que pensaba antes. Efectivamente, liberas una referencia, pero no cualquier referencia; y no es que se libere la "forma", pero únicamente una referencia a la misma. Donde dije: "Luego, al comprobar que no está creada la forma secundaria para crearla de nuevo se produce un error, porque, no está creada, pero tampoco puede crearse, puesto que su tipo ya no existe en la aplicación: ya se liberó." Debí decir: Esto es de lo peor, creo. Como bien dice roman, no se comprueba (con "if not Assigned(Form2) then ...") si la forma ha sido o no creada, sino si la referencia a ella es nula ("nil"). Y el tipo de la forma no puede liberarse: puede liberarse una determinada referencia al tipo, o un objeto de dicho tipo, pero no el tipo como tal. Donde dije: "La solución puede que pase por declarar una variable del tipo de la forma en donde vayas a emplear esta. Comprobar que no está ya creada una instancia de esta forma (secundaria) en la variable en cuestión. ¿No lo está? Se crea y se muestra la forma. ¿Lo está? Entonces no hace falta mostrarla, sino darla el foco, si es preciso." Quise decir: La solución no pasa por ahí, ya está claro, pero, ¿cómo pude pensar lo contrario? En realidad no hay que crear una variable del tipo de la forma, porque dicha variable ya está creada, quiere decirse, podemos utilizarla. Esta variable no guarda la forma como tal, sino una referencia a ella. Lo que debemos comprobar, como dice roman, es que dicha variable no guarda una referencia nula. Donde dije: "Utilizamos el evento "OnClose" de la forma secundaria para dar el valor "caFree" a la variable "Action" de tipo "TCloseAction"." Debí decir: Vamos a ver... ¿qué pretendía conseguir con esto? Efectivamente, dando el valor "caFree" a la variable "Action" que podemos encontrar en los parámetros del evento "OnClose" de un formulario, ¿qué liberamos? ¿Liberamos la referencia a dicho formulario? ¿El propio formulario? ¿El tipo del formulario? Liberamos la memoria asignada al objeto del tipo del formulario, pero no la referencia a este, la cual seguirá estando disponible... aunque ya no nos servirá, pues esta referencia será nula. Donde dije: "Aquí puedes ver un poco de código:"
Debí decir: Aquí está el código tanto de la parte en que se crea el formulario o forma como de la sentencia a utilizar en el evento "OnClose" de dicho formulario:
Donde dije: "No creas que me sé explicar todo lo que trato de explicarte a ti (¿Qué es esto?), al menos no todavía, pero el caso es que funcionar parece funcionar. Pruébalo tú a ver qué tal." Debí decir: No tengo mucha idea de cómo lo he hecho, pero, tecleando como un poseso he conseguido solucionar el problema, al menos, aparentemente. Tal vez alguien pueda aportar otro punto de vista, pero, tal vez esto pueda ayudarte en algo. Última edición por dec fecha: 10-05-2005 a las 20:41:13. Razón: (corrección del texto) |
#4
|
||||
|
||||
Pues me adelanté completamente
Hola,
Lo cierto es que me parecía haber probado a asignar el valor "nil" a la "forma" secundaria en su evento "OnClose". Juraría que lo hize, pero, no puede ser, otra cosa haría y me he confundido. Efectivamente, roman lleva razón: con darle el valor "nil" en el evento "OnClose" a la forma secundaria el problema se resuelve igualmente, bueno, igualmente no, de una manera más elegante que con "mi solución". Y además de que mi solución es menos elegante es que no está basada en la teoría que expone german... sino en no sé qué teoría... que así ha salido. Quiero decir que no comprendo aún muy bien ni lo que ha expuesto roman ni lo que yo mismo he expuesto: tendré que releer los comentarios para tratar de hacerlo. No sé cuántas veces. Actualización: No he querido borrar el comentario anterior en que trato de aportar una solución al problema aunque dicha solución no fuera acertada del todo, al menos. He preferido editarlo, de tal modo que se pueda leer en los apartados "Donde dije:" el comentario tal como lo realizé originalmente, y, en los apartados "Debí decir:" lo que, después de leer a roman y tratar de comprender su solución (que es la correcta) he podido comprender y valga la redundancia. Última edición por dec fecha: 10-05-2005 a las 20:40:10. Razón: (ampliar el texto) |
#5
|
|||
|
|||
Pues efectivamente, con el nil se soluciona
Como puse en el titulo, ya con el nil se soluciona, de hecho comprobe que crea una forma nueva cada vez que pulso el boton que manda crearla, ya decia yo que iba a ser algo sencillo pero que sino fuera por ustedes me hubiera costado mucho trabajo solucionar, una agradecimiento a ambos tanto por su ayuda y su rapida contestacion, es bueno saber que se puede contar con ayuda cuando se necesite, gracias a ambos.
|
#6
|
||||
|
||||
FreeAndNil
De la ayuda de Delphi:
Cita:
__________________
La violencia es el último recurso del incompetente. (Salvor Hardin) |
#7
|
|||
|
|||
No estoy seguro si libera completamente
Pues soy yo de nuevo con una nueva duda, ya decia yo que era mucha buena suerte que todo saliera bien, el problema que tengo es este:
Como les habia dicho creo la forma de manera dinamica y la muestro con un Show, el primer problema era que no sabia como liberar esa forma, gracias a la ayuda anterior probe con Nil y parecia que todo iba bien, pero....por cuestiones de programacion necesite asignarle el nombre de la forma despues de crear, el problema esta que al crear la forma la primera vez todo funciona bien, la cuestion es que cuando salgo de la forma y la libero con nil, al querer volverla a crear me dice que el objeto con el nombre que asigno ya existe, ahora mi duda, es si realmente la orden Nil libera totalmente la memoria o necesito de algo mas?
y para liberar en el OnClose pongo esto:
y como no estaba seguro de que nombre creaba, intente quitarle la asignacion del nombre y ver que nombre ponia la segunda vez que se creaba la forma y el nombre que se crea es este: Fpre_captura_1, entonces eso quiere decir que la primera forma todavia se queda en memoria o hace falta algo mas por liberar, ya intente usar freeandnil pero me manda un error de memoria y me cierra la aplicacion, les agradezco su ayuda de antemano. Última edición por jaaron fecha: 09-06-2005 a las 19:55:52. |
|
|
|