我在这里有一个系统,可以将自己拼成一个拼接在一起的位。有时这些位是在后台线程中呈现的,但有时当反馈的延迟非常重要时,这些位在主线程上同步呈现。
在主线程上,在名为createPatchView
的方法中调用此代码,patchView.createRenderingOperation()
返回执行呈现的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()
方法逻辑中的任何崩溃。
答案 0 :(得分:2)
将代码重构为main
并将其放在其他位置。从您的操作main
中调用该代码,并在需要时随时调用。
答案 1 :(得分:1)
您是否尝试将操作添加到主队列。那也会崩溃吗?
if async {
....
} else {
OperationQueue.main.addOperation(patchView.createRenderingOperation())
}