在主线程上同步启动 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
一些内部对象不知何故无效?在这一点上,感觉就像我在试图理解一个不再起作用的黑匣子的内部工作原理。
我是否错过了 运行 和 NSOperation
在 NSOperationQueue
之外的一些陷阱?
更新:
改为调用 patchView.createRenderingOperation().main()
是不好的形式吗?我想在这种情况下,我不需要以线程安全的方式跟踪操作的状态。我只需要它来完成它的工作并从那里继续执行。从理论上讲,这应该避免 start()
方法逻辑中嵌套的任何崩溃。
重构 main
中的代码并将其放在其他地方。从您的操作 main
中调用该代码,并在您希望它发生的任何时候调用。
您是否尝试过将操作添加到主队列。那也会崩溃吗?
if async {
....
} else {
OperationQueue.main.addOperation(patchView.createRenderingOperation())
}
我这里有一个系统,它以缝合在一起的位呈现自己。有时这些位在后台线程中呈现,但有时当反馈延迟非常重要时,这些位在主线程上同步呈现。
此代码在主线程上调用,在名为 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
一些内部对象不知何故无效?在这一点上,感觉就像我在试图理解一个不再起作用的黑匣子的内部工作原理。
我是否错过了 运行 和 NSOperation
在 NSOperationQueue
之外的一些陷阱?
更新:
改为调用 patchView.createRenderingOperation().main()
是不好的形式吗?我想在这种情况下,我不需要以线程安全的方式跟踪操作的状态。我只需要它来完成它的工作并从那里继续执行。从理论上讲,这应该避免 start()
方法逻辑中嵌套的任何崩溃。
重构 main
中的代码并将其放在其他地方。从您的操作 main
中调用该代码,并在您希望它发生的任何时候调用。
您是否尝试过将操作添加到主队列。那也会崩溃吗?
if async {
....
} else {
OperationQueue.main.addOperation(patchView.createRenderingOperation())
}