2010-09-08 8 views
6

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:

  1. MyLongRunningOp 0x1

El usuario navega al mapa. La cola ahora se ve así:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

Se mueven el mapa, que cancela MyMapOp 0x2 y añade MyMapOp 0x3:

  1. MyLongRunningOp 0x1
  2. 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?

Respuesta

1

Tuve (lo que creo que es) un problema similar con KVO en NSOperations.

Simplemente leyendo su descripción, mi primer instinto sería verificar las reglas de las colas de operación. ¿Es posible que una vez que lo entregue a la cola, la cola debe asumir la propiedad y, por lo tanto, no debe lanzarlo manualmente? (No estoy seguro de si eres o no).

Desde mi experiencia personal, y tal vez va a ayudar o no:

1) Cuando se cancela un artículo, quitar los observadores MVA de ella. Tuve la oportunidad de que los KVO no se desenlazaran cuando cualquiera de los lados se elimina.

2) Tenga en cuenta que las devoluciones de llamada KVO se ejecutan en el mismo hilo que la NSOperation. Por lo tanto, es posible que un objeto salga del alcance entre el momento en que inicia la operación y una devolución de llamada de KVO.

Es posible que pueda darte más ayuda si publicas el código. ¡Espero que lo anterior te haya sido útil!

+0

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

Cuestiones relacionadas