Tengo una aplicación que usa NSOperations
para administrar llamadas de servicio a una API web (las llamadas se basan en CURLOperation in Jon Wight's touchcode).¿Por qué NSOperationQueue en iPhone OS 3.1 se aferra a operaciones anuladas (y liberadas)?
Hay una cierta llamada que descarga ubicaciones de mapas cuando el centro de una vista de mapa cambia significativamente; dado que pueden acumularse tan rápido, si mueve el mapa, trato de cancelar agresivamente las operaciones obsoletas. Funciona muy bien en 4.0.
Sin embargo, en 3.1, parece que en ciertos casos la cola de operaciones se mantendrá en operaciones canceladas (y liberadas), causando un bloqueo cuando llegue al lugar donde deberían estar en la cola.
Aquí hay una ilustración.
Comienzo con una llamada de servicio relativamente peso pesado en la cola:
MyLongRunningOp 0x1
El usuario navega al mapa. La cola ahora se ve así:
MyLongRunningOp 0x1
MyMapOp 0x2
Se mueven el mapa, que cancela MyMapOp 0x2 y añade MyMapOp 0x3:
MyLongRunningOp 0x1
MyMapOp 0x3
MyMapOp 0x2
ahora se ha liberado, ya que se ha eliminado de la cola. Ahora termina MyLongRunningOp 0x1
. En las devoluciones de llamada KVO para establecer la clave isFinished en MyLongRunningOp
, veo que la cola de operaciones maneja la notificación y trata de agregar el MyMapOp 0x2
a unos NSArray
. Naturalmente, con NSZombies
habilitado,
[MyMapOp retain]: message sent to deallocated instance 0x2
Parece ser que el NSOperationQueue
es de alguna manera se aferran a un puntero a la operación cancelada/liberado, y tratar de activarlo después de la operación anterior haya terminado.
No he podido reproducir este comportamiento en 4.0, así que creo que es un error 3.1.
Tengo un montón de problemas para solucionarlo; por lo que yo sé, la única solución es nunca cancelar mis operaciones, lo que hace que la experiencia no sea óptima cuando la red es dudosa.
¿Alguien más ha experimentado esto? ¿Algunas ideas?
Creo que esto es correcto. En lugar de eliminarlo de la cola, solo debe enviar un mensaje de cancelación, que no lo libera o lo elimina de la cola, pero cuando llega a la parte superior de la cola, se saltará y se liberará. – makdad