ios - observer - ¿Dónde eliminar al observador para NSNotification en Swift?
swift nsnotificationcenter example (7)
A partir de iOS 9 (y OS X 10.11), no es necesario que elimine los observadores usted mismo, si no está utilizando observadores basados en bloques. El sistema lo hará por usted, ya que utiliza referencias débiles a cero para los observadores, donde puede.
Y si está utilizando observadores basados en bloques, asegúrese de
capturarse a sí mismo débilmente
usando
[weak self]
en la lista de captura del cierre, y
elimine al observador
en el método
deinit
.
Si no utiliza una referencia débil a sí mismo,
deinit
se
deinit
método de
deinit
(y, por lo tanto, la eliminación de ese observador) ya que el Centro de notificaciones mantendrá una fuerte referencia indefinidamente.
Puede encontrar más información en Foundation Release Notes para OS X v10.11 e iOS 9 .
Si el observador puede almacenarse como una referencia débil a cero, el almacenamiento subyacente almacenará al observador como una referencia débil a cero, alternativamente si el objeto no puede almacenarse débilmente (es decir, tiene un mecanismo personalizado de retención / liberación que evitaría el tiempo de ejecución de poder almacenar el objeto débilmente) almacenará el objeto como una referencia de puesta a cero no débil. Esto significa que los observadores no están obligados a anular el registro en su método de desasignación.
Los observadores basados en bloques a través del método - [NSNotificationCenter addObserverForName: object: queue: usingBlock] aún no deben registrarse cuando ya no estén en uso, ya que el sistema todavía tiene una fuerte referencia a estos observadores.
¿Dónde debo eliminar el observador para
NSNotification
en Swift, ya que
viewDidUnload
y
dealloc()
no están disponibles?
En Swift 4.2, esta es una de las formas en que puede eliminar observador
deinit {
NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}
configurar la notificación addObserver en la clase viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil)
}
Puedes usar tres métodos:
-
después de
popViewController
, volvernavigationController
odismissViewControllerAnimated
:deinit { print("Remove NotificationCenter Deinit") NSNotificationCenter.defaultCenter().removeObserver(self) }
-
viewDidDisappear
, elimine después de que ya sea el siguiente controlador de vista:override func viewDidDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self) }
-
viewWillDisappear
- antes de abrir la siguiente vista:override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self) }
Sintaxis de Swift 3.0:
NotificationCenter.default.removeObserver(self)
Swift proporciona un método deinit que se llama en instancias de clases antes de que se destruyan.
También es bueno si agrega su observador en
viewWillAppear()
y los elimina en
viewWillDisappear()
También quiero señalar que debes usar este método:
func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
En lugar de
func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol
Este último no eliminará al observador (se encontró con este problema recientemente). El primero eliminará al observador si está utilizando iOS9.
Utilice el siguiente método que funciona igual que
dealloc
.
deinit {
// Release all resources
// perform the deinitialization
}
Se llama a un desinfectante inmediatamente antes de que se desasigne una instancia de clase. Usted escribe desinicializadores con la palabra clave deinit, de forma similar a cómo se escriben los inicializadores con la palabra clave init. Los desinfectantes solo están disponibles en los tipos de clase.