guide basics memory-management swift

memory-management - basics - swift reference



¿Es necesario utilizar autoreleasepool en un programa Swift? (2)

El patrón de autoreleasepool se usa en Swift cuando se devuelven objetos de autorelease (creados por su código Objective-C o usando clases de Cocoa). El patrón de autorelease en Swift funciona de forma muy similar a lo que ocurre en Objective-C. Por ejemplo, considere esta representación Swift de su método ( NSImage instancia de objetos NSImage / UIImage ):

func useManyImages() { let filename = pathForResourceInBundle for _ in 0 ..< 5 { autoreleasepool { for _ in 0 ..< 1000 { let image = NSImage(contentsOfFile: filename) } } } }

Si ejecuta esto en Instrumentos, verá un gráfico de asignaciones como el siguiente:

Pero si lo haces sin el grupo de liberación automática, verás que el uso máximo de la memoria es mayor:

El grupo autoreleasepool permite administrar explícitamente cuando los objetos de liberación automática se desasignan en Swift, tal como lo hizo en Objective-C.

Nota: Cuando se trata de objetos nativos Swift, generalmente no recibirá objetos de liberación automática. Esta es la razón por la cual la presentación mencionó la advertencia de que solo se necesita esto al "trabajar con Objective-C", aunque me gustaría que Apple fuera más claro en este punto. Pero si se trata de objetos de Objective-C (incluidas las clases de Cocoa), pueden ser objetos de liberación automática, en cuyo caso, esta interpretación de Swift del patrón Objective-C @autoreleasepool sigue siendo útil.

En la página 17 de esta presentación WWDC14 , dice

Trabajando con Objective-C? Todavía tengo que administrar grupos de autorreleases
autoreleasepool {/ * code * /}

Qué significa eso? ¿Significa que si mi base de código no tiene ningún archivo Objective-C, autoreleasepool {} es necesario?

En una respuesta a una pregunta relacionada , hay un ejemplo donde autoreleasepool puede ser útil:

- (void)useALoadOfNumbers { for (int j = 0; j < 10000; ++j) { @autoreleasepool { for (int i = 0; i < 10000; ++i) { NSNumber *number = [NSNumber numberWithInt:(i+j)]; NSLog(@"number = %p", number); } } } }

Si el código anterior se traduce a Swift con la autoreleasepool , ¿Swift será lo suficientemente inteligente como para saber que la variable number debe liberar después de la primera } (como algunos otros idiomas)?


Si lo usaras en el código Objective-C equivalente, entonces lo usarías en Swift.

Swift será lo suficientemente inteligente como para saber que la variable de número debe ser liberada después del primer}

Solo si Objective-C lo hace Ambos operan a lo largo de las reglas de administración de la memoria Cocoa.

Por supuesto, ARC sabe que ese number fuera del alcance al final de esa iteración del ciclo, y si lo retuvo, lo liberará allí. Sin embargo, eso no le dice si el objeto se lanzó automáticamente, porque -[NSNumber numberWithInt:] puede haber devuelto o no una instancia liberada automáticamente. No hay manera de que pueda saber, porque no tiene acceso a la fuente de -[NSNumber numberWithInt:] .