2010-09-08 11 views
6

Ich habe eine App, die NSOperations verwendet, um Serviceaufrufe an eine Web-API zu verwalten (die Anrufe basieren auf CURLOperation in Jon Wight's touchcode).Warum hält NSOperationQueue auf dem iPhone OS 3.1 lange abgebrochene (und freigegebene) Operationen an?

Es gibt einen bestimmten Aufruf, der Kartenstandorte herunterlädt, wenn sich das Zentrum einer Kartenansicht signifikant ändert; Da diese sich so schnell stapeln können, versuche ich, wenn ich die Karte umherbewege, veraltete Operationen aggressiv abzubrechen. Es funktioniert gut auf 4.0.

Jedoch scheint es, dass in bestimmten Fällen die Operationswarteschlange an abgebrochenen (und freigegebenen) Operationen festhält, was zu einem Absturz führt, wenn sie den Ort erreicht, an dem sie sich in der Warteschlange befinden sollten.

Hier ist eine Illustration.

Ich beginne mit einem relativen Schwergewichts-Service-Aufruf in der Warteschlange:

  1. MyLongRunningOp 0x1

Der Benutzer navigiert zu der Karte. Die Warteschlange sieht nun wie folgt aus:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

Sie bewegen sich die Karte, die MyMapOp 0x2 annulliert und fügt MyMapOp 0x3:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x3

MyMapOp 0x2 ist jetzt freigegeben, da es aus der Warteschlange entfernt wurde. Jetzt MyLongRunningOp 0x1 endet. In den KVO-Callbacks zum Festlegen des isFinished-Schlüssels unter MyLongRunningOp sehe ich, dass die Operationswarteschlange die Benachrichtigung verarbeitet und versuche, die MyMapOp 0x2 zu einigen NSArray hinzuzufügen. Natürlich mit NSZombies aktiviert,

[MyMapOp retain]: message sent to deallocated instance 0x2 

Es scheint, dass die NSOperationQueue irgendwie auf hängt zu einem Zeiger auf den stornierten/freigegeben Betrieb und versuchen, sie zu aktivieren, nachdem die vorherige Operation beendet.

Ich konnte dieses Verhalten auf 4.0 nicht reproduzieren, also glaube ich, dass es ein 3.1-Fehler ist.

Ich habe viel Mühe, um es zu umgehen - soweit ich sagen kann, ist die einzige Problemumgehung, meine Operationen nie abzubrechen, was für eine suboptimale Erfahrung macht, wenn das Netzwerk fraglich wird.

Hat jemand anderes das erlebt? Irgendwelche Ideen?

Antwort

1

Ich hatte (was ich glaube) ein ähnliches Problem mit KVO auf NSOperationen.

Wenn ich nur Ihre Beschreibung lese, wäre mein erster Instinkt, die Regeln für Operationswarteschlangen zu überprüfen. Ist es möglich, dass die Warteschlange nach der Übergabe an die Warteschlange die Eigentumsrechte übernimmt und Sie sie daher nicht manuell freigeben sollten? (Nicht sicher, ob Sie es sind oder nicht).

Aus meiner persönlichen Erfahrung, und vielleicht wird es helfen, oder nicht:

1) Wenn Sie eine op abbrechen, entfernen Sie die KVO Beobachter davon. Ich habe es passiert, dass KVOs nicht gelinkt werden, wenn eine Seite gelöscht wird.

2) Beachten Sie, dass die KVO-Callbacks im selben Thread wie die NSOperation ausgeführt werden. Es ist also möglich, dass ein Objekt zwischen dem Zeitpunkt, zu dem Sie die Operation starten, und einem KVO-Callback außer Kraft gesetzt wird.

Ich könnte Ihnen möglicherweise mehr Hilfe geben, wenn Sie Code eingeben. Hoffentlich war das oben genannte für Sie nützlich!

+0

Ich glaube, das ist richtig. Anstatt es aus der Warteschlange zu entfernen, senden Sie ihm einfach eine -cancel-Nachricht, die es nicht freigibt oder aus der Warteschlange entfernt. Wenn es jedoch an die Spitze der Warteschlange gelangt, wird es übersprungen und freigegeben. – makdad