2016-07-19 22 views
2

達成しようとしていることが可能かどうかは確かです。キャンセルポイントなしで無限ループから抜け出すためのNSThreadの終了

PDFページを画像にレンダリングする際にバグがありました。アプリケーションで間違ったPDFドキュメントが発生し、レンダリングが文字通り永遠に(終了しない)行われているため、アプリケーションがユーザーによって停止されているようです。 Appleのプレビューアプリケーションでも問題のあるページが表示されても応答しなくなってしまっています。

PDFのレンダリング作業を2番目のスレッドに入れて問題を解決しようとしましたが、現在のスレッドはレンダリングがタイムアウトした場合は、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(1つのコア)を使用して使用できないスレッドを獲得しました。次にタイムアウトが発生すると、約200%のCPU(2つのコア)を使用する2つのスレッドが存在する可能性があります。それで私の結論は、抽選プロセスがキャンセルを求めていないということです。

[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を添付してください。

実行可能なオプションの1つは、外部プロセス(安全に終了することはできますが、これはiOSでは実行できません)に事前に飛ぶことで、レンダリングされたイメージをシャトルしたり、プレフライトに合格した場合

関連する問題