在主线程

时间:2016-07-19 19:21:46

标签: ios swift nsoperation

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

在主线程上,在名为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

crash stack

我还没有用附带的调试器来复制这个,这很令人沮丧,但崩溃日志显然已经出现了。

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

我是否错过了在NSOperation之外运行NSOperationQueue的一些陷阱?

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

2 个答案:

答案 0 :(得分:2)

将代码重构为main并将其放在其他位置。从您的操作main中调用该代码,并在需要时随时调用。

答案 1 :(得分:1)

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

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