2016-07-19 3 views
2

У меня есть система, которая делает себя в битах, которые сшиваются вместе. Иногда эти биты отображаются в фоновом потоке, но иногда, когда латентность обратной связи действительно важна, эти биты отображаются синхронно на основном потоке.Странный прерывистый сбой при синхронном запуске NSOperation на основной теме

Этот код вызывается в основном потоке в методе с именем createPatchView, а patchView.createRenderingOperation() возвращает подкласс NSOperation, который выполняет рендеринг. Версия async работает нормально, очередь операций забирает задание и обрабатывает его в фоновом режиме. Но другая ветка, где мы хотим сделать ее прямо сейчас дает мне прерывистые сбой.

// Figure out when to render it 
if async { 
    // Add the patch rendering job to the tile rendering queue. 
    tiledView.renderingQueue.addOperation(patchView.createRenderingOperation()) 
} else { 
    // Render and install the patch right now on the main thread for maximum responsiveness. 
    patchView.createRenderingOperation().start() // <-- CRASHES HERE 
} 

Вот детали аварии:

Signal: SIGSEGV: SEGV_ACCERR at 0x10 
Reason: objc_msgSend() selector name: observationInfo 

crash stack

И я еще повторить это с помощью отладчика прилагается, что расстраивает, но крешлогам явно поступают.

Итак, все в основном потоке создается операция рендеринга. Затем мы вызываем start() на эту операцию, чтобы сделать это прямо сейчас. Итак, теперь, до того, как он дойдет до любого из моего кода в операции main(), какой-то обработчик наблюдения за внутренним ключом стартует и вызывает observationInfo на каком-то внутреннем объекте, который как-то недействителен? На данный момент мне кажется, что я пытаюсь понять внутреннюю работу черного ящика, которая больше не работает.

Я пропустил какую-то ловушку пробега NSOperation за пределами NSOperationQueue?

UPDATE: Это плохая форма, чтобы позвонить по телефону patchView.createRenderingOperation().main()? Я полагаю, что в этом случае мне не нужно отслеживать состояние операции безопасным потоком. Мне просто нужно, чтобы это работало и продолжалось исполнение оттуда. Теоретически это должно избегать всякого сбоя, вложенного в логику метода start().

ответ

1

Измените код из main и поместите его в другое место. Вызовите этот код из вашей операции main и всякий раз, когда вы хотите, чтобы это произошло.

+0

Я думаю, что это ответ. Но когда у вас есть операция, у кого есть работа, она должна представлять материал, разумно просто использовать ее, но с разным временем. Почему это иногда падает, и иногда это нормально, я бы хотел, чтобы я знал. Отладка сбоев, которые происходят _inside_ кто-то компилируемый код отстой. –

+1

NSOperation связан с NSOperationQueue - он не предназначен для использования так, как вы хотите. Даже если у вас есть что-то для работы, это не будущее доказательство. –

1

Вы пытались добавить операцию в основную очередь. Будет ли это также катастрофовать?

if async { 
    .... 
} else { 
    OperationQueue.main.addOperation(patchView.createRenderingOperation()) 
} 
+0

Спасибо, но на самом деле этот код начался. Оказывается, «сделайте это сейчас» и «сделайте это в главной очереди» имеют довольно большие разницы во времени. Они оба происходят в основном потоке, но когда вы добавляете его в основную очередь, задание может не запускаться в течение неопределенного промежутка времени. –

+0

Но сбой при отправке в основную очередь? –

+0

Нет, я так не думаю. Который заставляет меня поверить, что вручную запускать «NSOperation» вне очереди следует избегать. Это, я полагаю, имеет смысл. –