2016-07-19 8 views
2

Я не уверен, что то, чего я пытаюсь достичь, возможно.Выход из NSThread для выхода из бесконечного цикла без отмены

У меня есть ошибка при рендеринге PDF-страниц в изображениях, похоже, что наше приложение сталкивается с ошибочными документами PDF когда-то, а некоторые рендеринги воспринимаются буквально навсегда (никогда не выходят), в результате чего наше приложение останавливается пользователем. (PDF действительно проблематичен, даже приложение Apple Preview перестает отвечать на запросы, когда отображается проблемные страницы.)

Я попытался исправить проблему, поставив рендеринг PDF во второй поток, в то время как текущий поток ожидает и попытайтесь отменить NSThread, если время ожидания рендеринга.

MAImageRepDrawing* imageRepDrawing = [[MAImageRepDrawing alloc] initWithImageRep:imgRep ...]; 
NSThread* thread = [[NSThread alloc] initWithTarget:imageRepDrawing selector:@selector(doDrawImageRep) object:nil]; 
[thread start]; 

double timeOutAt = 0; 
if (IMAGE_REP_RENDERING_TIMEOUT > 0) 
    timeOutAt = CFAbsoluteTimeGetCurrent() + (IMAGE_REP_RENDERING_TIMEOUT/1000.0); 
while (![imageRepDrawing isEnded]) { 
    sleep(1); 
    if ((IMAGE_REP_RENDERING_TIMEOUT > 0) && (CFAbsoluteTimeGetCurrent() > timeOutAt)) { 
     [thread cancel]; 
     break; 
    } 
} 

[thread release]; 
... 

К сожалению, он не полностью решить эту проблему, мне кажется, что механизм тайм-аут работает хорошо, и функция возвращает, и, таким образом, приложение по-прежнему. Но NSThread не отменяет, и приложение получает неиспользуемый поток, используя около 100% CPU (одно ядро). В следующий раз, когда произойдет тайм-аут, может быть два потока, использующих около 200% CPU (два ядра). И т. Д. Итак, мой вывод заключается в том, что процесс рисования не ищет отмены.

Я искал какой-то исправить, даже если это может быть уродливым, как применение [NSThread exit], но я не могу вызвать эту статическую функцию из текущего потока ... Я не вижу никакой другой полезной функции: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSThread_Class/

Есть ли что-нибудь еще, что можно было бы сделать?

Спасибо!

+1

На самом деле, если у вас есть образец PDF, который был поврежден, я был бы рад сообщить об ошибке с указанным PDF. Вы можете отправить его мне по электронной почте; bbum @ apple ... – bbum

+0

Просто отправил вам сообщение. Большое спасибо! : D –

ответ

4

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

Поскольку это убивает код Apple, пожалуйста, сообщите об ошибке и приложите ошибочный PDF-файл.

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