Swift Language
Gestión de la memoria
Buscar..
Introducción
Unmanaged ] [1]. [1]: https://developer.apple.com/reference/swift/unmanaged
Observaciones
Cuándo usar la palabra clave débil:
La palabra claveweak debe usarse, si un objeto referenciado puede ser desasignado durante la vida útil del objeto que contiene la referencia. Cuándo usar la palabra clave sin dueño:
Se debe usar la palabra claveunowned propietario, si no se espera que un objeto referenciado se desasigne durante la vida útil del objeto que contiene la referencia. Escollos
Un error frecuente es olvidarse de crear referencias a objetos, que se requieren para vivir después de que finaliza una función, como administradores de ubicación, administradores de movimiento, etc.Ejemplo:
class A : CLLocationManagerDelegate
{
init()
{
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.startLocationUpdates()
}
}
Este ejemplo no funcionará correctamente, ya que el administrador de ubicación se desasigna una vez que el inicializador regresa. La solución adecuada es crear una referencia fuerte como una variable de instancia:
class A : CLLocationManagerDelegate
{
let locationManager:CLLocationManager
init()
{
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.startLocationUpdates()
}
}
Ciclos de referencia y referencias débiles
Un ciclo de referencia (o ciclo de retención ) se llama así porque indica un ciclo en el gráfico de objetos :

Cada flecha indica un objeto que retiene otro (una referencia fuerte). A menos que el ciclo se rompa, la memoria de estos objetos nunca se liberará .
Se crea un ciclo de retención cuando dos instancias de clases se hacen referencia:
class A { var b: B? = nil }
class B { var a: A? = nil }
let a = A()
let b = B()
a.b = b // a retains b
b.a = a // b retains a -- a reference cycle
Ambas instancias vivirán hasta que el programa termine. Este es un ciclo de retención.
Referencias débiles
Para evitar los ciclos de retención, use la palabra clave weak o unowned al crear referencias para romper los ciclos de retención.
class B { weak var a: A? = nil } Las referencias débiles o sin propiedad no aumentarán el recuento de referencias de una instancia. Estas referencias no contribuyen a retener los ciclos. La referencia débil se vuelve nil cuando el objeto al que hace referencia se desasigna.
a.b = b // a retains b
b.a = a // b holds a weak reference to a -- not a reference cycle
Cuando trabaje con cierres, también puede usar weak y unowned en las listas de captura .
Gestión de memoria manual
Al interactuar con las API de C, es posible que desee retroceder el contador de referencia de Swift. Al hacerlo se logra con objetos no gestionados.
Si necesita suministrar un puntero de tipo punted a una función C, use el método de toOpaque de la estructura no Unmanaged para obtener un puntero sin fromOpaque y de fromOpaque para recuperar la instancia original:
setupDisplayLink() {
let pointerToSelf: UnsafeRawPointer = Unmanaged.passUnretained(self).toOpaque()
CVDisplayLinkSetOutputCallback(self.displayLink, self.redraw, pointerToSelf)
}
func redraw(pointerToSelf: UnsafeRawPointer, /* args omitted */) {
let recoveredSelf = Unmanaged<Self>.fromOpaque(pointerToSelf).takeUnretainedValue()
recoveredSelf.doRedraw()
}
Tenga en cuenta que, si utiliza passUnretained y sus homólogos, es necesario tomar todas las precauciones como con las referencias unowned .
Para interactuar con las API heredadas de Objective-C, uno podría querer afectar manualmente el conteo de referencias de un determinado objeto. Para eso Unmanaged tiene métodos respectivos de retain y release . No obstante, es más deseable usar passRetained y takeRetainedValue , que realizan la retención antes de devolver el resultado:
func preferredFilenameExtension(for uti: String) -> String! {
let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension)
guard result != nil else { return nil }
return result!.takeRetainedValue() as String
}
Estas soluciones siempre deben ser el último recurso, y las API nativas de idioma siempre deben ser preferidas.