En la página 17 de esta presentación de WWDC14 , dice
¿Trabaja con Objective-C? Aún tengo que administrar grupos de
liberación automática autoreleasepool {/ * código * /}
Qué significa eso? ¿Significa que si mi código base no tiene ningún archivo Objective-C, autoreleasepool {}
es innecesario?
En respuesta a una pregunta relacionada , hay un ejemplo en el que autoreleasepool
puede 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 se autoreleasepool
elimina, ¿Swift será lo suficientemente inteligente como para saber que la number
variable debe publicarse después de la primera }
(como lo hacen otros idiomas)?
memory-management
swift
Ethan
fuente
fuente
autoreleasepool
en Swift. Yo Ampliado de su pregunta y le pidió que en los foros dev .Respuestas:
El
autoreleasepool
patrón se usa en Swift cuando se devuelvenautorelease
objetos (creados por su código Objective-C o usando clases de Cocoa). Elautorelease
patrón en Swift funciona de manera muy similar a como lo hace en Objective-C. Por ejemplo, considere esta versión Swift de su método (instanciarNSImage
/UIImage
objetos):Si ejecuta esto en Instrumentos, verá un gráfico de asignaciones como el siguiente:
Pero si lo hace sin el grupo de liberación automática, verá que el uso máximo de memoria es mayor:
El le
autoreleasepool
permite administrar explícitamente cuándo se desasignan los objetos de liberación automática en Swift, al igual que pudo 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 solo se necesita esto cuando se "trabaja con Objective-C", aunque me gustarí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 versión Swift del
@autoreleasepool
patrón Objective-C sigue siendo útil.fuente
println
endeinit
, y se hace muy fácil verificar precisamente cuando se cancela la asignación objetos. O obsérvelo en Instrumentos. En respuesta a su pregunta, parece que los objetos Swift se devuelven desde funciones con +1 de retención de recuento (no objetos de liberación automática), y la persona que llama administrará sin problemas la propiedad desde ese punto (por ejemplo, si el objeto devuelto cae fuera del alcance y cuándo, se desasigna inmediatamente, no se coloca en un grupo de liberación automática).NSImage
/UIImage
objects y manifesté el problema de manera más consistente (y, francamente, este es un ejemplo más común del problema, ya que el uso máximo de memoria a menudo solo es problemático cuando se trata de objetos más grandes; un ejemplo práctico de esto podría ser una rutina para cambiar el tamaño de un montón de imágenes). También reproduje el comportamiento que llama al código Objective-C que crea explícitamente objetos de liberación automática. No me malinterpretes: creo que necesitamos grupos de liberación automática en Swift con menos frecuencia que en Objective-C, pero todavía tiene un papel que desempeñar.pathForResource:ofType:
repetidamente.pathForResource:ofType:
ejemplo ya no funciona en Xcode 6.3 / Swift 1.2. :)Si lo usara en el código Objective-C equivalente, lo usaría en Swift.
Solo si Objective-C lo hace. Ambos operan según las reglas de administración de memoria de Cocoa.
Por supuesto, ARC sabe que eso
number
queda fuera de 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 fue liberado automáticamente, ya-[NSNumber numberWithInt:]
que puede haber devuelto o no una instancia liberada automáticamente. No hay forma de que pueda saberlo, porque no tiene acceso a la fuente de-[NSNumber numberWithInt:]
.fuente
autoreleasepool
construcción es completamente innecesaria. Pero si su código Swift está manejando objetos Objective-C (incluidos los objetos Cocoa), estos siguen patrones de liberación automática y, por lo tanto, laautoreleasepool
construcción se vuelve útil.