Eliminar observadores de forma segura
Evite fugas y bloqueos causados por observadores obsoletos.
Eliminar observadores de forma segura es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 3 de 4. 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 4 lecciones en total.
Eliminar observadores de forma segura
Debe eliminar los observadores cuando ya no sean necesarios. Un observador que siga registrado puede activarse después de que su propietario haya desaparecido, lo que provoca errores o, con las API antiguas, cierres inesperados.
Por qué es importante eliminarlos
Históricamente, los observadores basados en selectores debían eliminarse en deinit para evitar enviar mensajes a un objeto desasignado.
import Foundation
class Watcher: NSObject {
override init() { super.init() }
deinit { NotificationCenter.default.removeObserver(self) }
}
print("Removes itself on deinit")removeObserver(self)
Llamar a removeObserver(self) anula en una sola llamada todas las observaciones realizadas por ese objeto.
import Foundation
class VM: NSObject {
func stop() { NotificationCenter.default.removeObserver(self) }
}
VM().stop()
print("Removed all observations for self")Eliminar un nombre específico
Puede eliminar una sola observación pasando el nombre y el objeto, y mantener intactas las demás.
import Foundation
let center = NotificationCenter.default
let obj = NSObject()
let name = Notification.Name("ping")
center.removeObserver(obj, name: name, object: nil)
print("Removed a specific observation")Observadores basados en tokens
La versión basada en closures de addObserver devuelve un token opaco. Consérvelo y elimine el observador usando ese token.
import Foundation
let center = NotificationCenter.default
let name = Notification.Name("ping")
let token = center.addObserver(forName: name, object: nil, queue: nil) { _ in }
center.removeObserver(token)
print("Removed via token")Almacenar el token
Almacene el token en una propiedad para que exista mientras necesite la observación y elimínelo cuando termine.
import Foundation
class Model {
var token: NSObjectProtocol?
func start() {
token = NotificationCenter.default.addObserver(
forName: Notification.Name("x"), object: nil, queue: nil) { _ in }
}
func stop() {
if let t = token { NotificationCenter.default.removeObserver(t) }
}
}
let m = Model(); m.start(); m.stop()
print("Lifecycle managed")Limpieza automática con deinit
Elimine el token en deinit para que la observación termine cuando se desasigne su propietario.
import Foundation
class Owner {
var token: NSObjectProtocol?
deinit { if let t = token { NotificationCenter.default.removeObserver(t) } }
}
print("Token removed on deinit")Nota sobre el ciclo de vida moderno
En los entornos de ejecución recientes, los observadores añadidos con la API basada en bloques se eliminan automáticamente cuando se desasigna el token, pero la eliminación explícita sigue siendo la opción segura y clara.
import Foundation
// Holding the token in a property controls its lifetime.
class C { var token: NSObjectProtocol? }
print("Token lifetime equals observation lifetime")Evitar ciclos de retención
Si una closure de observador captura self con fuerza, use [weak self] para evitar un ciclo de retención que impida la desasignación.
import Foundation
class VM {
var token: NSObjectProtocol?
func start() {
token = NotificationCenter.default.addObserver(
forName: Notification.Name("x"), object: nil, queue: nil) { [weak self] _ in
self?.handle()
}
}
func handle() { print("handled") }
}
VM().start()La eliminación doble es segura
Eliminar un observador que ya no existe no causa ningún problema, por lo que la limpieza preventiva no provocará un error.
import Foundation
let center = NotificationCenter.default
let obj = NSObject()
center.removeObserver(obj)
center.removeObserver(obj) // no harm
print("Safe to remove twice")Resumen de buenas prácticas
Prefiera closures basadas en tokens, almacene el token, elimínelo en deinit y capture self débilmente. Así mantendrá correctamente los ciclos de vida de las observaciones.
import Foundation
class Best {
var token: NSObjectProtocol?
deinit { token.map { NotificationCenter.default.removeObserver($0) } }
}
print("Followed best practices")Comprobación rápida
¿Cómo se elimina un observador basado en una closure añadido con addObserver(forName:...)?
Repaso
Elimine siempre los observadores que ya no necesite. Use removeObserver(self) para los observadores basados en selectores y el token devuelto para los observadores basados en closures; almacene el token, haga la limpieza en deinit y capture self débilmente. Siguiente: cómo se compara el patrón observer con otras alternativas.
Preguntas frecuentes
¿La lección «Eliminar observadores de forma segura» es gratis?
Sí — el texto completo de «Eliminar observadores de forma segura» 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 4 lecciones en total.
¿Qué aprenderé en «Eliminar observadores de forma segura»?
Evite fugas y bloqueos causados por observadores obsoletos. 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 3 de 4.
¿Cuánto tiempo toma la lección «Eliminar observadores de forma segura»?
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
- Publicar y observar notificaciones
- Cargas userInfo de las notificaciones
- Eliminar observadores de forma segura
- Alternativas al patrón Observer