2012-05-02 26 views
13

Estoy un poco desconcertado sobre qué usar para almacenar objetos en una lista. Hasta ahora he usado TList y he liberado cada elemento en un bucle. Luego descubrí TObjectList que hace esto automáticamente desde Free. Entonces vi esto desde el doc de TList.Clear:Borrar un TList o una TObjectList

llamada Clear para vaciar la matriz de artículos y establecer el Count a 0. Clear también libera la memoria utilizada para almacenar la matriz Items y establece el Capacity a 0.

Así que es básicamente lo mismo. Así

para TList

mylist.Clear; 
myList.Free; 

es el mismo que para TObjectList?

myList.Free; 

Puede TObjectList sólo se puede utilizar para los artículos como clases o puedo guardar los registros?

+1

La parte que cita es solo "básicamente la misma" si no lee la documentación TObjectList cuidadosamente: "Si la propiedad OwnsObjects se establece en true (valor predeterminado), TObjectList controla la memoria de sus objetos, liberando un objeto cuando se reasigna su índice, cuando se elimina de la lista con el método Eliminar, Eliminar o Borrar, o cuando la instancia TObjectList se destruye a sí misma ". La documentación de TList no dice nada sobre ese comportamiento. Esa es la diferencia fundamental entre las dos clases. –

Respuesta

18

1. TList no liberará los elementos, con Clear o Free.

aList.Clear;

Simplemente configurará aList.Count := 0 sin liberar los elementos aList.Items[]. Entonces perderás memoria. Se necesita de una conexión explícita como tal:

for i := 0 to aList.Count-1 do 
    TObject(aList[i]).Free; 

Pero esto es lo que hace TObjectList ... :)

Sobre TObjectList, vale la pena decir que está llamando TObjectList.DestroyClear.

Así

aObjectList.Clear; 
aObjectList.Free; 

es exactamente el mismo que

aObjectList.Free; 

2. Para almacenar una lista de registros, puede utilizar una matriz dinámica.

Obtendrá todos los métodos TList (y más) con nuestro dynamic array wrapper. Es decir, Add/Delete/Clear/Count/IndexOf/Find ...

Tiene características de serialización integradas (en binario o JSON), clasificación automática y comparación (usando RTTI) que no existen con un TList/TObjectList. De Delphi 5 y más tarde.

Con la versión más moderna de Delphi, puede usar genéricos para manejar la matriz dinámica, si no desea utilizar una biblioteca de terceros.

+3

Solo una aclaración sobre 'TObjectList'. Tiene una propiedad: 'OwnsObjects' (predeterminado = verdadero) que controla si los objetos en la lista se liberan cuando se eliminan los elementos. –

+0

@LURD Tienes razón. Esta propiedad puede ser útil, pero también engañosa: puede suponer que los objetos se liberarán, pero si establece 'OwnObjects: = false' en algún lugar del código (incluso en tiempo de ejecución), se perderían fácilmente la memoria o los recursos: por lo tanto ¡usado con cuidado! Prefiero una separación clara de 'TList/TObjectList'. –

10

No es lo mismo TList.Clear solo libera la memoria asignada para almacenar los punteros, no los objetos a los que apuntan. Para evitar fugas de memoria, debe liberar la memoria usted mismo, como ha estado haciendo, o usar TObjectList. Para responder a la segunda pregunta, TObjectList no es compatible con el almacenamiento de los registros. Necesitará usar TList (o alguna otra cosa) en ese caso.

+0

Sin embargo, saber gestionar los registros en un 'TList' requiere bastante esfuerzo. – NGLN

7

Si está utilizando una versión reciente de Delphi, le sugiero que utilice una lista genérica.

En este momento, probablemente necesite hacer mucho casting cuando use los objetos de la lista. Con una lista genérica ya no tienes que hacer eso.

Por ejemplo, si usted tiene:

TMyObject = class(TObject); 

luego de hacer la lista de la siguiente manera:

TMyObjectList = TObjectList<TMyObject>; 

Hay un artículo en el Embarcadero Wiki:

http://docwiki.embarcadero.com/CodeExamples/XE8/en/Generics_Collections_TObjectList_(Delphi)

7

Lea lo que dice la documentación con más cuidado:

Claro que también libera la memoria utilizada para almacenar el conjunto items

Sólo la memoria de la propia matriz se libera, no la memoria utilizada por los elementos individuales dentro de la matriz.

-1

Ver realmente el código TObjectList en contnrs.pas OwnObjects no hace nada. FOwnObjects es una variable declarada en la parte privada de TObjectList que no se utiliza en ningún lugar en el código TObjectList (excepto que solo asigna el valor), y no hay ningún procedimiento anulado Clear en él.

Así que me temo que es necesario liberar la memoria de la misma manera que en TList.

+1

La propiedad 'TObjectList.OwnsObjects' es verdadera por defecto. Puede cambiar el valor de la propiedad después de la creación. Si esta propiedad es verdadera al llamar 'TObjectList.Free', todos los objetos en la lista serán desasignados automáticamente. –

Cuestiones relacionadas