dispatch_source_cancel on a suspended timer causes EXC_BAD_INSTRUCTION

前端 未结 1 786
忘了有多久
忘了有多久 2020-12-31 02:50

I\'m trying to cancel and then release a suspended timer but when I invoke \'dispatch_release\' on it, I immediately get EXC_BAD_INSTRUCTION.

Is this not a valid se

相关标签:
1条回答
  • 2020-12-31 03:03

    The reason it crashes is because of this code:

    void
    _dispatch_source_xref_release(dispatch_source_t ds)
    {
        if (slowpath(DISPATCH_OBJECT_SUSPENDED(ds))) {
            // Arguments for and against this assert are within 6705399
            DISPATCH_CLIENT_CRASH("Release of a suspended object");
        }
        _dispatch_wakeup(ds);
        _dispatch_release(ds);
    }
    

    So, you can't release a dispatch_source_t that has been suspended. You probably want to just not suspend it in resetTimer I guess.

    Whilst I can't find anything in the docs for why they have written it like this (and the comment alludes to the pros and cons being in a radar we'll never see), all I can do is refer to the docs where it says:

    You can suspend and resume the delivery of dispatch source events temporarily using the dispatch_suspend and dispatch_resume methods. These methods increment and decrement the suspend count for your dispatch object. As a result, you must balance each call to dispatch_suspend with a matching call to dispatch_resume before event delivery resumes.

    Whilst that doesn't say you can't release a dispatch source that's been suspended, it does say you have to balance each call so I'm assuming it's something along the lines of it's using a dispatch semaphore under-the-hood which have to be balanced before they can be released. That's just my guess though :-).

    As for "can I invoke dispatch_suspend within a timer source's event_handler block". I'm pretty sure you can, yes, as per the docs for dispatch_suspend:

    The suspension occurs after completion of any blocks running at the time of the call.

    0 讨论(0)
提交回复
热议问题