У меня есть приложение, которое использует NSOperations
для управления вызовами служб к веб-API (вызовы основаны на CURLOperation в Jon Wight's touchcode ).
Существует определенный вызов, который загружает местоположения карты, когда центр изображения карты значительно изменяется; поскольку они могут накапливаться так быстро, если вы перемещаете карту, я стараюсь агрессивно отменять устаревшие операции. Он отлично работает в 4.0.
Однако в 3.1 кажется, что в некоторых случаях очередь операций будет удерживаться до отмененных (и освобожденных) операций, вызывая сбой, когда он достигает места, в котором они должны быть в очереди.
Вот иллюстрация.
Я начинаю с относительно тяжелого вызова службы в очереди:
MyLongRunningOp 0x1
Пользователь переходит к карта. Очередь теперь выглядит так:
MyLongRunningOp 0x1
MyMapOp 0x2
Они перемещают карту, что отменяет MyMapOp 0x2 и добавляет MyMapOp 0x3:
MyLongRunningOp 0x1
MyMapOp 0x2
MyMapOp 0x3 [12104 1199709] освобожден, поскольку был удален из очереди. Теперь
MyLongRunningOp 0x1
завершается. В обратных вызовах KVO для установки ключа isFinished на MyLongRunningOp
я вижу, что очередь операций обрабатывает уведомление, и пытаюсь добавить MyMapOp 0x2
в некоторый NSArray
. Естественно, при включенном NSZombies
,
[MyMapOp retain]: message sent to deallocated instance 0x2
Похоже, что NSOperationQueue
каким-то образом цепляется за указатель на отмененную / освобожденную операцию и пытается активировать ее после завершения предыдущей операции.
Мне не удалось воспроизвести такое поведение в 4.0, поэтому я считаю, что это ошибка 3.1.
У меня много проблем с ее решением - насколько я могу судить, единственный обходной путь - никогда не отменять мои операции, что делает неоптимальным опыт, когда сеть становится ненадежной.
Кто-нибудь еще сталкивался с этим? Есть идеи?