_dispatch_queue_xref_dispose EXC_BREAKPOINT

Seeing a iOS 11 only crash on the line when nil out a timer. Did not see this in iOS 10.


if (timerIsSuspended) {

dispatch_resume(_myTimer); //balance suspend and resume calls

}

dispatch_source_cancel(_myTmer);

_myTimer = nil; //EXC_BREAKPOINT / EXC_ARM_BREAKPOINT in _dispatch_queue_xref_dispose


Saw an old thread from 2015 where we should actually call resume after cancel. Is this now enforced in iOS 11?

https://forums.developer.apple.com/message/46175#46175


Or wait to nil the timer in a cancellation handler? This code is in dealloc.

Replies

I've seen the same thing; what I've figured out to fix it for iOS11 is to add a cancellation handler that strongly holds a reference until the thing is cancelled


if (timerIsSuspended) {
    dispatch_resume(_myTimer); //balance suspend and resume calls
}

__block dispatch_source_t previousTimer = _myTimer;
dispatch_source_set_cancel_handler(_myTimer, ^{
    previousTimer = nil; // dealloc will happen here after everything is done cancelling
});

dispatch_source_cancel(_myTimer); // note: this asyncronously cancels

_myTimer = nil; // works fine since this doesn't actually dealloc now
  • @gabebear thank you so much! Your tricky hack saved my life! :D

Add a Comment