El conteo automático de referencias ( ARC ) es una función de administración de memoria del compilador Clang que proporciona un conteo automático de referencias para los lenguajes de programación Objective-C y Swift . En tiempo de compilación, inserta en los mensajes de código de objeto y [1] [2] que aumentan y disminuyen el recuento de referencias en tiempo de ejecución, marcando para desasignar esos objetos cuando el número de referencias a ellos llega a cero. retain
release
ARC se diferencia del seguimiento de la recolección de basura en que no existe un proceso en segundo plano que desasigne los objetos de forma asincrónica en tiempo de ejecución. [3] A diferencia del seguimiento de la recolección de basura, ARC no maneja los ciclos de referencia automáticamente. Esto significa que mientras haya referencias "fuertes" a un objeto, no se desasignará. En consecuencia, las referencias cruzadas fuertes pueden crear puntos muertos y pérdidas de memoria . Depende del desarrollador romper los ciclos utilizando referencias débiles . [4]
Apple Inc. implementa ARC en sus sistemas operativos, como macOS ( OS X ) e iOS . El soporte limitado (ARCLite) [5] ha estado disponible desde Mac OS X Snow Leopard e iOS 4 , con soporte completo en Mac OS X Lion e iOS 5 . [6] La recolección de basura se declaró obsoleta en OS X Mountain Lion , a favor de ARC, y se eliminó de la biblioteca de tiempo de ejecución de Objective-C en macOS Sierra . [7] [8]
C objetivo
El compilador aplica las siguientes reglas cuando ARC está activado:
retain
,release
,retainCount
,autorelease
Odealloc
no puede ser enviado a los objetos. En su lugar, el compilador inserta estos mensajes en tiempo de compilación automáticamente, incluso[super dealloc]
cuandodealloc
se anula. [9]// Sin ARC - ( void ) dealloc { [[ NSNotificationCenter defaultCenter ] removeObserver : self ]; [ super desalloc ]; }// Con ARC - ( void ) dealloc { [[ NSNotificationCenter defaultCenter ] removeObserver : self ]; // [super dealloc] se llama automáticamente }
- Los programas no pueden emitir directamente entre
id
yvoid *
. [9] Esto incluye la conversión entre objetos Foundation y objetos Core Foundation. Los programas deben usar conversiones especiales, o llamadas a funciones especiales, para decirle al compilador más información sobre la vida útil de un objeto.// Sin ARC - ( NSString * ) giveMeAString { CFStringRef myString = [ self someMethodThatCreatesACFString ]; NSString * newString = ( NSString * ) myString ; return [ newString autorelease ]; }// Con ARC - ( NSString * ) giveMeAString { CFStringRef myString = [ self someMethodThatCreatesACFString ]; // el recuento de retención es 1 NSString * newString = ( __bridge_transfer NSString * ) myString ; // la propiedad ahora se ha transferido a ARC return newString ; }
- Se puede utilizar un grupo de liberación automática para asignar objetos temporalmente y retenerlos en la memoria hasta que el grupo se "vacíe". Sin ARC,
NSAutoreleasePool
se puede crear un objeto para este propósito. En su@autoreleasepool
lugar, ARC usa bloques, que encapsulan la asignación de los objetos temporales y los desasigna cuando se llega al final del bloque. [9]// Sin ARC - ( void ) loopThroughArray: ( NSArray * ) array { for ( id object in array ) { NSAutoreleasePool * pool = [[ NSAutoreleasePool alloc ] init ]; // Crea muchos objetos temporales [ drenaje de la piscina ]; } } // Con ARC - ( void ) loopThroughArray: ( NSArray * ) array { for ( id object in array ) { @autoreleasepool { // Crea muchos objetos temporales } } }
- Los programas no pueden llamar a las funciones
NSAllocateObject
yNSDeallocateObject
[9] - Los programas no pueden utilizar punteros de objeto en las estructuras de C (
struct
s) [9] - Los programas no pueden utilizar zonas de memoria (
NSZone
) [9] - Para cooperar adecuadamente con el código que no es ARC, los programas no deben usar ningún método o propiedad declarada (a menos que se elija explícitamente un getter diferente) que comience con
new
. [9]
Declaraciones de propiedad
ARC introduce algunos nuevos atributos de declaración de propiedad, algunos de los cuales reemplazan los antiguos.
Sin ARC | Con ARC | Con ARCLite [Nota 1] |
---|---|---|
retain | strong | |
assign (para tipos de objetos) | weak | unsafe_unretained |
copy |
- ^ ARCLite es ARC pero sin poner a cero las referencias débiles (se usa cuando se implementa en un entorno operativo con menos capacidad de lo que requiere ARC).
Poner a cero referencias débiles
Poner a cero las referencias débiles es una función en Objective-C ARC que borra (establece nil
) automáticamente las variables locales de referencia débil, las variables de instancia y las propiedades declaradas inmediatamente antes de que el objeto al que se apunta comience a desasignarse. Esto asegura que el puntero vaya a un objeto válido o nil
, y evita punteros colgantes . Antes de la introducción de esta función, las "referencias débiles" se referían a referencias que no se retenían, pero que no estaban configuradas nil
cuando el objeto al que apuntaban se desasignó (equivalente a unsafe_unretained
en ARC), lo que posiblemente conduzca a un puntero colgando. Por lo general, el programador tenía que asegurarse de que todas las posibles referencias débiles a un objeto se establecieran en cero manualmente cuando se desasignaba. Poner a cero las referencias débiles obvia la necesidad de hacer esto.
La puesta a cero de las referencias débiles se indica mediante el atributo de propiedad declarado weak
o mediante el atributo de variable __weak
.
La puesta a cero de referencias débiles solo está disponible en Mac OS X Lion (10.7) o posterior y iOS 5 o posterior, porque requieren soporte adicional del tiempo de ejecución de Objective-C. Sin embargo, algunas clases de OS X no admiten actualmente referencias débiles. [9] El código que usa ARC pero necesita ser compatible con versiones del sistema operativo más antiguas que las anteriores no puede usar referencias débiles de reducción a cero y, por lo tanto, debe usar unsafe_unretained
referencias débiles. Existe una biblioteca de terceros llamada PLWeakCompatibility [1] que permite utilizar la reducción a cero de referencias débiles incluso en estas versiones de SO más antiguas.
Convirtiendo a
Xcode 4.2 o posterior proporciona una forma de convertir código a ARC. [10] A partir de Xcode 4.5, se encuentra eligiendo Editar> Refactorizar> Convertir a Objective-C ARC ... Aunque Xcode convertirá automáticamente la mayoría del código, es posible que algunos códigos tengan que convertirse manualmente. Xcode informará al desarrollador cuando surjan casos de uso más complejos, como cuando una variable se declara dentro de un grupo de liberación automática y se usa fuera de él o cuando dos objetos deben ser puenteados sin cargo con conversiones especiales.
Rápido
En Swift, las referencias a objetos son fuertes, a menos que se declaren weak
o unowned
. Swift requiere un manejo explícito de nil con el tipo Optional: un tipo de valor que puede tener un valor o ser nil. Un tipo Opcional debe manejarse "desenvolviéndolo" con una declaración condicional , lo que permite un uso seguro del valor, si está presente. Por el contrario, cualquier tipo no opcional siempre tendrá un valor y no puede ser nulo.
var myString : String // Solo puede ser una cadena var myOtherString : String ? // Puede ser una cadena o nuloif let myString = myOtherString { // Desenvuelve la impresión opcional ( myString ) // Imprime la cadena, si está presente }
En consecuencia, una referencia fuerte a un objeto no puede ser de tipo Opcional, ya que el objeto se mantendrá en el montón hasta que se desasigne la propia referencia. Una referencia débil es de tipo Opcional, ya que el objeto se puede desasignar y la referencia se puede establecer en nil. Las referencias sin dueño se encuentran en el medio; no son fuertes ni de tipo Opcional. En cambio, el compilador asume que el objeto al que un punto de referencia sin propietario no se desasigna mientras la referencia misma permanezca asignada. Esto se usa generalmente en situaciones en las que el objeto de destino en sí mismo contiene una referencia al objeto que contiene la referencia sin propietario.
var strongReference : MiClase // referencia fuerte, no puede ser nulo débil var WeakReference : MiClase ? // referencia débil, puede ser nulo sin dueño var unownedReference : MiClase // referencia débil, no puede ser nulo
Swift también se diferencia de Objective-C en su uso y fomento de tipos de valor en lugar de tipos de referencia . La mayoría de los tipos de la biblioteca estándar de Swift son tipos de valor y se copian por valor, mientras que las clases y los cierres son tipos de referencia y se pasan por referencia. Debido a que los tipos de valor se copian cuando se pasan, se desasignan automáticamente con la referencia que los creó. [11]
Ver también
- Puntero inteligente
Referencias
- ^ Siracusa, John (20 de julio de 2011). "Mac OS X 10.7 Lion: la revisión de Ars Technica" . Ars Technica . Ars Technica. En la sección "Recuento automático de referencias" . Consultado el 17 de noviembre de 2016 .
- ^ Kochan, Stephen G. (2011). Programación en Objective-C (4ª ed.). Boston, Mass .: Addison-Wesley. págs. 408 . ISBN 978-0321811905.
- ^ Hoffman, Kevin (2012). Sams aprende a desarrollar aplicaciones para Mac OS X Lion en 24 horas . Indianápolis, Indiana: Sams. pp. 73 . ISBN 9780672335815.
- ^ "General" . Recuento automático de referencias . LLVM.org . Consultado el 15 de agosto de 2012 .
- ^ "Índice de disponibilidad de funciones de Objective-C" . Apple, Inc . Consultado el 14 de octubre de 2013 .
- ^ Sakamoto, Kazuki (2012). Pro Multithreading y gestión de memoria para iOS y OS X con ARC, Grand Central Dispatch y Blocks . Presione. págs. xii. ISBN 978-1430241164.
- ^ Siracusa, John (25 de julio de 2012). "OS X 10.8 Mountain Lion: la revisión de Ars Technica" . Ars Technica . En la sección "Mejoras de Objective-C" . Consultado el 17 de noviembre de 2016 .
- ^ "Notas de la versión de Xcode 8" . Desarrollador de Apple . 27 de octubre de 2016. Archivado desde el original el 19 de marzo de 2017 . Consultado el 19 de marzo de 2017 .
- ^ a b c d e f g h "Transición a las notas de la versión ARC" . Consultado el 14 de septiembre de 2012 .
- ^ "Novedades de Xcode 4.2 - Recuento automático de referencias" . Apple Inc. Archivado desde el original el 20 de agosto de 2012 . Consultado el 3 de octubre de 2012 .
- ^ "Tipos de valor y referencia" . Desarrollador de Apple . 15 de agosto de 2014 . Consultado el 17 de noviembre de 2016 .
enlaces externos
- Transición a ARC - Biblioteca para desarrolladores de iOS
- " Recuento automático de referencias " en el lenguaje de programación Swift