Según tengo entendido, todo lo que se cree con una asignación , un nuevo o una copia debe liberarse manualmente. Por ejemplo:
int main(void) {
NSString *string;
string = [[NSString alloc] init];
/* use the string */
[string release];
}
Mi pregunta, sin embargo, ¿no sería esto igualmente válido ?:
int main(void) {
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
NSString *string;
string = [[[NSString alloc] init] autorelease];
/* use the string */
[pool drain];
}
objective-c
memory-management
nsautoreleasepool
foundationkit
James Sumners
fuente
fuente
an object
debería seran object that is a subclass of NSObject or NSProxy and doesn't override -autorelease
.NSAutoreleasePool: drenaje frente a liberación
Dado que la función de
drain
yrelease
parece estar causando confusión, puede valer la pena aclararlo aquí (aunque esto está cubierto en la documentación ...).Estrictamente hablando, desde la perspectiva del panorama general no
drain
es equivalente a :release
En un entorno contado por referencias,
drain
realiza las mismas operaciones querelease
, por lo que los dos son en ese sentido equivalentes. Para enfatizar, esto significa que no filtra una piscina si usa endrain
lugar derelease
.En un entorno de recolección de basura, no
release
es una operación. Por tanto, no tiene ningún efecto.drain
, por otro lado, contiene una sugerencia para el coleccionista de que debe "recopilar si es necesario". Por lo tanto, en un entorno de recolección de basura, el usodrain
ayuda al sistema a equilibrar los barridos de recolección.fuente
NSAutoreleasePool
. Esto se debe a que las agrupaciones funcionan como una pila. La creación de instancias de un grupo empuja ese grupo a la parte superior de la pila de grupos de liberación automática de subprocesos.-release
hace que ese grupo salga de la pila Y cualquier grupo que se colocó encima de él, pero que por alguna razón no se abrieron.Como ya se señaló, su segundo fragmento de código es correcto.
Me gustaría sugerir una forma más sucinta de usar el grupo de liberación automática que funciona en todos los entornos (recuento de referencias, GC, ARC) y también evita la confusión de drenaje / liberación:
En el ejemplo anterior, tenga en cuenta el bloque @autoreleasepool . Esto está documentado aquí .
fuente
@autoreleasepool
bloque con ARC.No, tu estas equivocado. La documentación establece claramente que, en caso de que no sea GC, -drain es equivalente a -release, lo que significa que NSAutoreleasePool no se filtrará .
fuente
NSAutoreleasePool
: developer.apple.com/mac/library/documentation/Cocoa/Conceptual/…Lo que leí de Apple: "Al final del bloque del grupo de liberación automática, los objetos que recibieron un mensaje de liberación automática dentro del bloque reciben un mensaje de liberación: un objeto recibe un mensaje de liberación por cada vez que se envió un mensaje de liberación automática dentro del bloque. "
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html
fuente
enviar la liberación automática en lugar de la liberación a un objeto extiende la vida útil de ese objeto al menos hasta que se agote la piscina (puede ser más larga si el objeto se retiene posteriormente). Un objeto se puede colocar en el mismo grupo varias veces, en cuyo caso recibe un mensaje de liberación cada vez que se coloca en el grupo.
fuente
Si y no. Terminaría liberando la cadena de memoria pero "filtrando" el objeto NSAutoreleasePool en la memoria usando drenaje en lugar de liberación si ejecuta esto en un entorno de recolección de basura (no administrado por memoria). Esta "fuga" simplemente hace que la instancia de NSAutoreleasePool sea "inalcanzable" como cualquier otro objeto sin punteros fuertes debajo de GC, y el objeto se limpiará la próxima vez que se ejecute GC, lo que muy bien podría ser directamente después de la llamada a
-drain
:De lo contrario, es similar a cómo se
-release
comporta sin GC, sí. Como han dicho otros, no-release
es una operación en GC, por lo que la única forma de asegurarse de que el grupo funcione correctamente en GC es a través-drain
, y-drain
en no GC funciona exactamente como-release
en no GC, y podría decirse que comunica su funcionalidad más claramente como bien.Debo señalar que su declaración "cualquier cosa llamada con new, alloc o init" no debe incluir "init" (pero debe incluir "copy"), porque "init" no asigna memoria, solo configura el objeto (constructor Moda). Si recibió un objeto asignado y su función solo llamó a init como tal, no lo liberaría:
Eso no consume más memoria de la con la que ya comenzó (asumiendo que init no crea una instancia de los objetos, pero usted no es responsable de ellos de todos modos).
fuente
-[NSAutoreleasePool release]
en un entorno de recolección de basura no es una operación.-[NSAutoreleasePool drain]
funciona tanto en entornos de recuento de referencias como de recolección de basura.