Ciclos de retención y cómo romperlos con weak/unowned
Detecte ciclos de retención entre objetos y closures, y rómpalos de forma segura mediante referencias weak y unowned .
Ciclos de retención y cómo romperlos con weak/unowned es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 2 de 3. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 3 lecciones en total.
¿Qué es un ciclo de retención?
Un ciclo de retención ocurre cuando varios objetos (o closures) mantienen referencias strong entre sí, de modo que ARC nunca llega a cero. Rompa los ciclos con weak o unowned.
Ciclo objeto ↔ objeto
Dos referencias strong en ambas direcciones crean una fuga de memoria: ninguno de los objetos puede llegar a cero.
final class Owner {
var gadget: Gadget?
deinit { print("Owner deinit") }
}
final class Gadget {
var owner: Owner?
deinit { print("Gadget deinit") }
}
// Strong ⇄ strong (cycle)
var o: Owner? = Owner()
var g: Gadget? = Gadget()
o!.gadget = g
g!.owner = o
o = nil // no deinit
g = nil // still no deinit (leak)Romperlo con weak
Haga que uno de los lados sea weak (a menudo la referencia inversa, como delegate/owner) para permitir que ARC libere ambos objetos.
final class Owner2 {
var gadget: Gadget2?
deinit { print("Owner2 deinit") }
}
final class Gadget2 {
weak var owner: Owner2? // weak breaks cycle; becomes nil automatically
deinit { print("Gadget2 deinit") }
}
var o2: Owner2? = Owner2()
var g2: Gadget2? = Gadget2()
o2!.gadget = g2
g2!.owner = o2
o2 = nil // Owner2 deinit
g2 = nil // Gadget2 deinitCiclo de closure (self strong)
Los closures capturan las variables con strong de forma predeterminada. Si el objeto también es propietario del closure, se forma un ciclo.
final class TimerClient {
var tick: (() -> Void)?
deinit { print("TimerClient deinit") }
func start() {
// BAD: closure strongly captures self; self keeps tick strongly
tick = {
print("tick from", self) // strong capture of self
}
}
}
var c: TimerClient? = TimerClient()
c!.start()
c = nil // no deinit — closure holds self stronglyRomperlo con listas de captura
Utilice [weak self] (opcional) para una limpieza segura; utilice [unowned self] únicamente si se garantiza que self seguirá activo cuando se ejecute el closure.
final class TimerClient2 {
var tick: (() -> Void)?
deinit { print("TimerClient2 deinit") }
func start() {
// Use [weak self] when self can go away before tick runs
tick = { [weak self] in
guard let self = self else { return } // safe unwrap
print("tick from", self)
}
// Alternative when lifetime is guaranteed: [unowned self]
// tick = { [unowned self] in print("tick from", self) }
}
}
var c2: TimerClient2? = TimerClient2()
c2!.start()
c2 = nil // deinit now prints — no cycleLista de comprobación
Lista de comprobación:
- ¿Hay referencias en ambas direcciones? Haga que un lado sea weak (por ejemplo, delegate).
- ¿Hay closures almacenados en un tipo? Capture [weak self] y desenvuélvalo de forma segura.
- Utilice [unowned self] únicamente cuando la duración de vida esté garantizada; de lo contrario, puede provocar un fallo.
Weak frente a unowned en closures
Comprobación rápida: ¿Qué lista de captura es más segura cuando el objeto puede liberarse?
Resumen
Resumen: Identifique los ciclos en objetos y closures. Rómpalos utilizando weak o unowned según corresponda; en caso de duda, prefiera weak.
Preguntas frecuentes
¿La lección «Ciclos de retención y cómo romperlos con weak/unowned» es gratis?
Sí — el texto completo de «Ciclos de retención y cómo romperlos con weak/unowned» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 3 lecciones en total.
¿Qué aprenderé en «Ciclos de retención y cómo romperlos con weak/unowned»?
Detecte ciclos de retención entre objetos y closures, y rómpalos de forma segura mediante referencias weak y unowned . Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Swift Academy?
No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 3.
¿Cuánto tiempo toma la lección «Ciclos de retención y cómo romperlos con weak/unowned»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Swift Academy?
Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Fundamentos de ARC: strong / weak / unowned
- Ciclos de retención y cómo romperlos con weak/unowned
- Tipos de valor para reducir el uso compartido