A diferencia de otros lenguajes como Java o Kotlin, Swift no tiene un recolector de basura. En su lugar, utiliza una técnica mucho más rápida denominada Automatic Reference Counting (ARC).
En la mayoría de los casos, esto significa que no tenemos que preocuparnos del manejo de memoria en Swift. Simplemente funciona, como si de un recolector de basura se tratase. Es decir, ARC swift liberará automáticamente la memoria utilizada por una clase cuando ésta no vaya a ser utilizada nunca más.
¿Cómo sabe ARC si puede liberar la memoria utilizada por una instancia?
Muy simple: ARC lleva la cuenta de cuántas propiedades, constantes o variables apuntan hacia una instancia.
Cada vez que asignamos una variable a una instancia de una clase, la cuenta de referencias (a partir de ahora,<strong>retainCount</strong>
) aumenta en +1. Si asignamos la misma instancia a 3 variables diferentes, su cuenta de referencias será 3. ¿Fácil, no?
var myVariable1: SomeObject = SomeObject()
var myVariable2 = myVariable1
var myVariable3 = myVariable1
Sólo cuando esa cuenta de referencias (<strong>retainCount</strong>
) baje hasta cero, ARC considerará que esa instancia nunca se va a volver a utilizar y se puede eliminar de memoria.
👀 OJO: Cuando intentas acceder a una instancia de una clase que ya ha sido eliminada de memoria, se produce un crash en tu aplicación.
Manos al teclado : Xcode
1) Aumentando la cuenta de referencias
Supongamos que tenemos una clase <strong>Author</strong>
que representa a un escritor de libros:
class Author {
// MARK: Properties
let name: String
// MARK: Initialization
init(name: String) {
self.name = name
}
deinit {
print(“Author called \(name) is being deinitialized")
}
}
La clase <strong>Author</strong>
tiene un método <strong>init</strong>
para crear el objeto y un método <strong>deinit</strong>
que se va a ejecutar cuando la instancia se vaya a eliminar de memoria.
Vamos a crear ahora una variable de tipo <strong>Author?</strong>
para poder asignarla a <strong>nil</strong>
o a una instancia de tipo <strong>Author</strong>
.
var author1: Author? = Author(name: “George R. R. Martin”)
En estos momentos, se crea una referencia fuerte (<strong>strong</strong>
reference) entre el símbolo <strong>author1</strong>
y la instancia de tipo <strong>Author</strong>
. Se llama referencia fuerte (strong
) porque aumenta en +1 la cuenta de referencias de la instancia.
Object | retainCount |
Author | 1 |
Vamos a crear ahora otras dos variables y asignarle el mismo objeto al que apunta <strong>author1</strong>
:
var author2 = author1
var author3 = author1
Con cada nueva asignación, se está creando una nueva referencia fuerte, que suma +1 a la cuenta de referencias total, que ahora mismo es igual a 3.
Object | <strong>retainCount</strong> |
Author | 3 |
2) Decrementando la cuenta de referencias
Ahora vamos a hacer lo contrario.
Vamos a ir decrementando la cuenta de referencias (<strong>retainCount</strong>
) de la instancia. Esto lo podemos conseguir asignando alguna de las variables a <strong>nil</strong>
:
author1 = nil
author2 = nil
Cada vez que hacemos esto, la cuenta de referencias disminuye en uno.
Object | <strong>retainCount</strong> |
Author | 1 |
Recuerda que ARC en iOS sólo liberará la memoria utilizada por la instancia cuando su cuenta de referencias llegue a cero. Ahora mismo, sigue siendo igual a 1, porque todavía podemos acceder a ella a través de <strong>author3</strong>
.
Vamos a hacer que llegue a cero asignando <strong>author3</strong>
también a <strong>nil</strong>
:
author3 = nil
// Se imprime por pantalla:
// “Author called George R. R. Martin is being deinitialized"
Fíjate cómo se ejecuta el código dentro de <strong>deinit</strong>
. Esto quiere decir que ARC ha liberado la memoria utilizada por esta instancia, ya que su cuenta de referencias fuertes ha llegado a cero. O dicho de otro modo, ya no quedan referencias fuertes (strong
) apuntando a la instancia, y por tanto, es seguro eliminarlo.
Únete a la newsletter para no perderte ningún nuevo tutorial: recibe un email cuando se publiquen nuevos artículos o vídeos y no pierdas la oportunidad de seguir aprendiendo.
Conclusión
Aunque Swift no tiene un recolector de basura, utiliza otra técnica llamada ARC que consiste en llevar la cuenta de referencias fuertes que apuntan hacia una instancia.
Esto es mucho más rápido que cualquier otra técnica y nos permite olvidarnos, en la mayoría de las ocasiones, del manejo de memoria en Swift.
Pero existen ocasiones en las que le tenemos que echar una mano a nuestro amigo ARC en Swift. En el próximo artículo te cuento uno de ellos.
Mientras tanto, si te ha gustado lo que has leído, te invito a subscribirte a la comunidad de alexandrefreire.com y compartir en redes sociales.