在主线程上同步启动 NSOperation 时出现奇怪的间歇性崩溃

Weird intermittent crash on synchronous start of an NSOperation on main thread

我这里有一个系统,它以缝合在一起的位呈现自己。有时这些位在后台线程中呈现,但有时当反馈延迟非常重要时,这些位在主线程上同步呈现。

此代码在主线程上调用,在名为 createPatchView 的方法中,patchView.createRenderingOperation() returns NSOperation 的子类进行渲染。异步版本工作正常,操作队列选择作业并在后台处理它。但是我们现在 想要渲染它的另一个分支给我间歇性崩溃。

// 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

而且我还没有用附加的调试器复制它,这令人沮丧,但崩溃日志显然正在出现。

因此,所有在主线程上,创建渲染操作。然后我们调用 start() 立即执行该操作。所以现在在它到达操作 main() 方法中的任何 my 代码之前,一些内部键值观察处理程序启动并调用 observationInfo 一些内部对象不知何故无效?在这一点上,感觉就像我在试图理解一个不再起作用的黑匣子的内部工作原理。

我是否错过了 运行 和 NSOperationNSOperationQueue 之外的一些陷阱?

更新: 改为调用 patchView.createRenderingOperation().main() 是不好的形式吗?我想在这种情况下,我不需要以线程安全的方式跟踪操作的状态。我只需要它来完成它的工作并从那里继续执行。从理论上讲,这应该避免 start() 方法逻辑中嵌套的任何崩溃。

重构 main 中的代码并将其放在其他地方。从您的操作 main 中调用该代码,并在您希望它发生的任何时候调用。

您是否尝试过将操作添加到主队列。那也会崩溃吗?

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