Alex Wayne Alex Wayne - 1 year ago 48
Swift Question

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

I have a system here that renders itself in bits that get stitched together. Sometimes those bits are rendered in an background threads, but sometimes when latency of feedback is really important those bits are rendered synchronously on the main thread.

This code is called on the main thread, in a method named

, and
returns a subclass of
that does the rendering. The async version works fine, the operation queue picks up the job and handles it in the background. But the other branch where we want to render it right now is giving me intermittent crashes.

// Figure out when to render it
if async {
// Add the patch rendering job to the tile rendering queue.
} else {
// Render and install the patch right now on the main thread for maximum responsiveness.
patchView.createRenderingOperation().start() // <-- CRASHES HERE

Here's the crash detail:

Signal: SIGSEGV: SEGV_ACCERR at 0x10
Reason: objc_msgSend() selector name: observationInfo

crash stack

And I've yet to replicate this with the debugger attached, which is frustrating, but the crash logs are clearly coming in.

So, all on the main thread, the render operation is created. Then we call
on that operation to do it right now. So now before it gets to any of my code in the operations
method, some internal key value observation handler kicks off and calls
on some internal object that's somehow invalid? At this point it feels like I'm trying to understand the inner workings of a black box that doesn't work anymore.

Have I missed some pitfall of running an
outside of an

Is it bad form to call
instead? I suppose in this case, I don't need to keep track of the status of the operation in a thread safe way. I just need it to do it's work and continue execution from there. In theory, this should avoid whatever is crashing nested inside the logic of the

Answer Source

Refactor the code out of main and put it somewhere else. Call that code from your operation's main and whenever you want it to happen.