¿Es necesario utilizar autoreleasepool en un programa Swift?

Resuelto Ethan asked hace 10 años • 3 respuestas

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

¿Trabajando con Objective-C? Todavía tengo que administrar los grupos de liberación automática
autoreleasepool { /* código */ }

¿Qué significa eso? ¿Significa que si mi código base no tiene archivos Objective-C, autoreleasepool {}es innecesario?

En una respuesta a una pregunta relacionada , hay un ejemplo que autoreleasepoolpuede resultar ú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 y autoreleasepoolse elimina, ¿Swift será lo suficientemente inteligente como para saber que la numbervariable debe publicarse después de la primera }(como lo hacen otros idiomas)?

Ethan avatar Sep 16 '14 11:09 Ethan
Aceptado

El autoreleasepoolpatrón se usa en Swift al devolver autoreleaseobjetos (creados por su código Objective-C o usando clases Cocoa). El autoreleasepatrón en Swift funciona de manera muy similar a como lo hace en Objective-C. Por ejemplo, considere esta interpretación Swift de su método (creación de instancias NSImage/ UIImageobjetos):

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 con 5pequeñas colinas (debido al bucle for externo), como el siguiente:

con grupo de liberación automática

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

sin grupo de liberación automática

Le autoreleasepoolpermite administrar explícitamente cuándo se desasignan objetos de liberación automática en Swift, tal como lo hizo en Objective-C.

Nota: Cuando se trata de objetos nativos de Swift, generalmente no recibirá objetos de liberación automática. Es por eso que la presentación mencionó la advertencia de que sólo se necesita esto cuando "se trabaja con Objective-C", aunque desearía que Apple fuera más claro en este punto. Pero si se trata de objetos Objective-C (incluidas las clases Cocoa), pueden ser objetos de liberación automática, en cuyo caso esta interpretación Swift del @autoreleasepoolpatrón Objective-C sigue siendo útil.

Rob avatar Sep 16 '2014 23:09 Rob

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

¿Swift será lo suficientemente inteligente como para saber que la variable numérica debe liberarse después del primer }

Sólo si Objective-C lo hace. Ambos operan según las reglas de administración de memoria de Cocoa.

Por supuesto, ARC sabe que eso numbersale del alcance al final de esa iteración del ciclo y, si lo retuvo, lo liberará allí. Sin embargo, eso no le indica si el objeto se lanzó automáticamente, porque -[NSNumber numberWithInt:] puede haber devuelto o no una instancia de liberación automática. No hay manera de que puedas saberlo porque no tienes acceso a la fuente de -[NSNumber numberWithInt:].

newacct avatar Sep 16 '2014 20:09 newacct