NSTask не отправляет уведомление о прекращении

Я зарегистрировался для NSTaskDidTerminateNotification объекта NSTask. Все работает нормально, но для запуска задачи требуется время, поэтому я перевел запуск в фоновый режим (с помощью PerformSelectorInBackground).

  • регистрация в центре уведомлений и создание самой задачи происходит в основном потоке
  • через несколько секунд задача запускается в фоновом режиме
  • уведомления больше не приходят :(

Можно ли как-то настроить код, чтобы уведомления снова работали?


person Marius    schedule 05.11.2013    source источник
comment
на всякий случай можете выложить код для инициализации, регистрации и код блока выполняемый асинхронно   -  person lead_the_zeppelin    schedule 05.11.2013
comment
@lead_the_zeppelin все довольно стандартно, асинхронный код — это просто команда [запуск задачи]. Я также пытался переместить регистрацию уведомлений туда, но это не сработало. В любом случае, сейчас это не имеет значения, потому что я сейчас делаю waitUntilExit после запуска, а после этого я вручную вызываю метод, который должен был вызвать центр уведомлений. И он снова работает, так что я думаю, проблема решена.   -  person Marius    schedule 05.11.2013


Ответы (2)


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

Если единственное, что вы делаете с -performSelectorInBackground:..., — это вызываете метод -launch задачи, тогда поток не задерживается и не запускает свой цикл выполнения. (Точно так же нельзя полагаться на то, что рабочие потоки, обслуживающие очереди GCD, сохранят существующие или запустят свои циклы выполнения.) Вы можете вызвать более сложный метод в фоновом режиме, который запускает задачу, а затем запускает цикл выполнения, но это не должно не нужно.

Вы уверены, что запуск задачи занимает сколько-нибудь заметное количество времени? Это действительно не должно. NSTask спроектирован так, чтобы задачи можно было создавать, запускать и отслеживать в основном потоке, не делая его зависающим.

person Ken Thomases    schedule 05.11.2013
comment
это требует времени, так как задача заключается в туннельном соединении ssh, а их довольно много. Я решил проблему, дождавшись завершения задачи вручную (в фоновом режиме) и отправив уведомление в основной поток. В любом случае, спасибо за ваше объяснение, я думаю, что оно очень информативно, поэтому я отмечу это как ответ. - person Marius; 06.11.2013
comment
Выполнение задачи может занять некоторое время, но запуск не должен занимать много времени. *пожал плечами* - person Ken Thomases; 06.11.2013
comment
Что ж, это так. 1-3 секунды. И так как таких соединений несколько - влияние довольно очевидно :) - person Marius; 06.11.2013

во-первых NSTask не является потокобезопасным . вам нужно соблюдать осторожность при использовании его экземпляра из отдельных потоков или полностью избегать его.

во-вторых, насколько я могу судить, NSNotifications доставляются только в потоке, в котором опубликовано уведомление. Уведомление отправляется самим объектом NSTask, который, по-видимому, завершается во вторичном потоке, но вы зарегистрировались для получения уведомления в основном потоке. Дополнительные сведения см. в документах.

Не могли бы вы просто обработать всю последовательность задач и уведомлений в фоновом потоке?

person Brad Allred    schedule 05.11.2013
comment
Пытался сделать это в фоновом потоке, но уведомление не пришло. В любом случае, я не хотел тратить на это больше времени, поэтому я просто выдал waitUntilExit в потоке bg, и это делает то же самое для меня, так что проблема исправлена. - person Marius; 06.11.2013