Почему NSOperationQueue на iPhone OS 3.1 поддерживает долго отмененные (и выпущенные) операции? - PullRequest
6 голосов
/ 08 сентября 2010

У меня есть приложение, которое использует NSOperations для управления служебными вызовами в веб-API (вызовы основаны на CURLOperation в сенсорном коде Джона Уайта ).

Есть определенный вызовзагружает местоположения на карте, когда центр представления карты существенно изменяется;поскольку они могут складываться очень быстро, если вы перемещаете карту, я стараюсь агрессивно отменять устаревшие операции.Он отлично работает на 4.0.

Однако на 3.1 кажется, что в некоторых случаях очередь операций будет удерживать отмененные (и освобожденные) операции, вызывая сбой, когда достигнет места, где они должны быть вqueue.

Вот иллюстрация.

Я начинаю с относительно тяжелого вызова службы в очереди:

  1. MyLongRunningOp 0x1

Пользователь переходит на карту.Очередь теперь выглядит следующим образом:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

Они перемещают карту, что отменяет MyMapOp 0x2 и добавляет MyMapOp 0x3:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x3

MyMapOp 0x2 теперь освобождено, так как оно было удалено из очереди.Теперь MyLongRunningOp 0x1 заканчивается.В обратных вызовах KVO для установки ключа isFinished на MyLongRunningOp я вижу, что очередь операций обрабатывает уведомление и пытается добавить MyMapOp 0x2 к некоторому NSArray.Естественно, с включенным NSZombies,

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

Похоже, что NSOperationQueue каким-то образом привязан к указателю на отмененную / отпущенную операцию и пытается активировать ее после завершения предыдущей операции.

Мне не удалось воспроизвести это поведение на 4.0, поэтому я считаю, что это ошибка 3.1.

У меня много проблем с этим - насколько я могу судитьЕдинственный обходной путь - никогда не отменять мои операции, что делает работу неоптимальной, когда сеть становится ненадежной.

Кто-нибудь еще испытывал это?Есть идеи?

1 Ответ

1 голос
/ 10 мая 2011

У меня была (как я полагаю) похожая проблема с использованием KVO в NSOperations.

Просто прочитав ваше описание, мой первый инстинкт должен был бы проверить правила для очередей операций. Возможно ли, что после того, как вы передадите его в очередь, очередь должна стать владельцем, и, следовательно, вы не должны освобождать ее вручную? (Не уверен, если вы или нет).

Из моего личного опыта, а может и поможет или нет:

1) Когда вы отменяете оп, снимите с него наблюдателей КВО. У меня было такое, что КВО не связываются, когда любая из сторон удаляется.

2) Имейте в виду, что обратные вызовы KVO выполняются в том же потоке, что и операция NSO. Таким образом, объект может выйти из области видимости между моментом запуска операции и обратным вызовом KVO.

Я мог бы помочь вам, если вы отправите код. Надеюсь, что выше было полезно для вас!

...