退出 NSThread 以从没有取消点的无限循环中跳出

Exiting a NSThread to break out from an infinite loop without cancellation point

我不确定我想要实现的目标是否可行。

我在将 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];
...

不幸的是,它并没有完全解决问题,似乎超时机制运作良好,功能returns,因此应用程序继续。但是 NSThread 并没有取消,应用程序使用了大约 100% 的 CPU(一个核心)获得了一个无用的线程。下次发生超时时,可能有两个线程使用了大约 200% 的 CPU(两个核心)。等等所以我的结论是画图过程不是找取消

我正在寻找某种修复方法,即使它可能很难看,例如调用 [NSThread exit],但我无法从当前线程调用此静态函数...我没有看到任何其他有用的功能: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSThread_Class/

还有什么可以做的吗?

谢谢!

无法从所述线程外部确定性地终止线程,因为无法知道目标线程的状态或终止它可能产生的副作用。

由于这会杀死 Apple 的代码,请提交错误并附上错误的 PDF。

一个可行的选择可能是在外部进程中进行飞行前处理(可以安全地终止它——但你不能在 iOS 上执行此操作),然后穿梭于渲染的图像或然后重新-如果飞行前通过,则在您的应用程序中呈现。