Obtener "desaconsejado mientras los observadores de valor clave todavía estaban registrados con él". Errores después de la conversión a ARC

StackOverflow https://stackoverflow.com/questions/7811865

Pregunta

Estoy usando esta clase:

https://github.com/alexleutgoeb/alpickerview

Como convertí en ARC, recibo este error después de hacer clic en PickerView un par de veces:

2011-10-18 14:10:19.424 MappingApp[3398:10d03] An instance 0x73c7cd0 of class CustomTapGestureRecognizer was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info: <NSKeyValueObservationInfo 0x5d93430> (<NSKeyValueObservance 0x5d933f0: Observer: 0x5d66eb0, Key path: state, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x746b180>)

El error apunta a la clase CustomTApGestureCoginizer y la última línea de este método:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    // Simple hack, set recognizer state to possible as tap begins
    self.state = UIGestureRecognizerStatePossible;
}

En CheckView, tengo este método:

- (void)didMoveToSuperview {
    gestureRec = [[CustomTapGestureRecognizer alloc] initWithTarget:nil action:nil];
    gestureRec.numberOfTapsRequired = 1;
    [gestureRec addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
    [[self superview] addGestureRecognizer:gestureRec];
}

Y, el removerObServer, que sé que puede causar este problema, está en el trato de CheckView. ¿Debería mover esto a otro lugar? ¿Alguien tiene alguna otra idea que pueda estar causando este problema? Nunca sucedió antes del arco.

¿Fue útil?

Solución

Supongo que el método didMoveToSuperview en el CheckView La clase se llama más de una vez causando el gestureRec Variable de instancia a reasignar y el anterior CustomTapGestureRecognizer La instancia considerada no ha dejado referencias por ARC y luego se desanimó (causando el mensaje de advertencia de que alguien todavía está observando la instancia).

Intenta agregar NSLog(@"didMoveToSuperview: self=%@ gestureRec=%@", self, gestureRec); al comienzo de didMoveToSuperview Para ver si este es el caso.

Si es así, una solución rápida es probablemente algo como esto, pero no lo he probado yo mismo ni sé mucho sobre el código.

- (void)didMoveToSuperview {
  if (gestureRec != nil) {
    [gestureRec removeObserver:self forKeyPath:@"state"];
  }
  gestureRec = [[CustomTapGestureRecognizer alloc] initWithTarget:nil action:nil];
  gestureRec.numberOfTapsRequired = 1;
  [gestureRec addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
  [[self superview] addGestureRecognizer:gestureRec];   
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top