objective c - Fallo con removeObserver: forKeyPath: en Foundation
objective-c crash (2)
Tengo algunos problemas con los siguientes registros de bloqueo recuperados de la sección "Bloqueos" en Xcode. Solo unos pocos dispositivos se ven afectados por este informe de bloqueo.
He analizado el problema, pero supongo que es un error en el marco de Apple. Pero no puedo encontrar una manera de replicarlo.
Aquí una discusión similar: Ayuda con el bloqueo en removeObserver: forKeyPath:.
¿Algún consejo?
Subproceso 0 nombre: Subproceso 0 bloqueado:
0 Fundación
0x23507591 _NSKeyValueReplaceObservationInfoForObject + 69 (NSKeyValueObserving.m: 1166)1 Fundación
0x23506fe7 - [NSObject (NSKeyValueObserverRegistration) _removeObserver: forProperty:] + 327 (NSKeyValueObserving.m: 1552)2 Fundación
0x23506b03 - [NSObject (NSKeyValueObserverRegistration) removeObserver: forKeyPath:] + 163 (NSKeyValueObserving.m: 1696)3 Fundación
0x235069a7 - [NSObject (NSKeyValueObserverRegistration) removeObserver: forKeyPath: context:] + 219 (NSKeyValueObserving.m: 1663)4 ApplicationName 0x0002e233 - [Supervisor removeObjectObserver: forKeyPath:] + 115 (Supervisor.m: 344)
donde removeObjectObserver:forKeyPath:
es
- (void) removeObjectObserver:(id)object forKeyPath:(NSString *)keyPath {
@try {
[object removeObserver:self forKeyPath:keyPath context:PrivateKVOContext];
} @catch (NSException *exception) { }
}
Observers
en Objective-C
deben usarse con especial atención: no agregue el mismo tiempo de múltiplos de observador a la propiedad del mismo objeto, y ajuste la eliminación si hay uno:
if ([self observationInfo]) {
@try {
[self removeObserver:self forKeyPath:keyPath];
}
@catch (NSException *exception) {}
}
Estás experimentando bloqueos porque intentas eliminar dos veces al observador o estás eliminando un observador inexistente.
Debe agregar observers
esta manera:
[yourObject addObserver:self forKeyPath:keypath options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil/yourContext];
EDITAR: Puede eliminar un observador en un objeto ya desasignado, lo que da como resultado este bloqueo.
if (object && [self observationInfo]) {
@try {
[self removeObserver:self forKeyPath:keyPath];
}
@catch (NSException *exception) {}
}
Normalmente tienes un ivar para poder saber si el keypath de un objeto está observando en ese momento o no. Me gusta @property (...) BOOL textFieldTextObserving; Y sus métodos de agregar / eliminar observaciones deben verificar esta propiedad antes de agregar / eliminar para evitar agregar / eliminar observador dos veces. También puede usar NSDictionary si hay muchos objetos de observación y keypaths (para mantener @ (BOOL) como objetos e -identificadores como claves).
De todos modos, hacer cosas con @ try-exception no es una forma recomendada de Objective-C. Apple dice:
"You should not use a try-catch block in place of standard programming checks for Objective-C methods. In the case of an NSArray, for example, you should always check the array''s count to determine the number of items before trying to access an object at a given index. The objectAtIndex: method throws an exception if you make an out-of-bounds request so that you can find the bug in your code early in the development cycle—you should avoid throwing exceptions in an app that you ship to users."
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ErrorHandling/ErrorHandling.html