开发者

Grand Central Dispatch problems with dispatch_release

开发者 https://www.devze.com 2023-03-09 14:14 出处:网络
I have a problem with a GCD solution I\'ve made. I have a thread that runs in 开发者_C百科the background, it updates the application in a given interval. For this I use a timer.

I have a problem with a GCD solution I've made. I have a thread that runs in 开发者_C百科the background, it updates the application in a given interval. For this I use a timer.

However if the user wants to change this interval, I call

dispatch_source_cancel(timer);

Which is defined as

dispatch_source_set_cancel_handler(timer, ^{
   dispatch_release(timer);
});

And then restart the the thread. When the interval is changed a second time the app crashes. Even though I do recreate the timer with a new interval.

I could avoid releasing the timer, but then I'll have memory leeks.

Any advice, what to do?

EDIT: Timer is created like this

timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, autoRefreshQueue);

if(!timer) {
    return;
}

dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, refreshRate * NSEC_PER_SEC), refreshRate * NSEC_PER_SEC, refreshRate * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
    //do work
});


I don't think this is the answer. dispatch_source_cancel doesn't cancel immediately, synchronously.

  • man dispatch_source_cancel

    The dispatch_source_cancel() function asynchronously cancels the dispatch source, preventing any further invocation of its event handler block. Cancellation does not interrupt a currently executing handler block (non-preemptive).

Thus, restarting the thread might invoke the blocks concurrently if autoRefreshQueue is Global Queue.

How did you restart the thread?

EDITED:

However there are no mentions of calling dispatch_source_set_timer twice (or more) for the same Dispatch Source in the references or the manuals, dispatch_source_set_timer in libdispatch/src/source.c seems ok for it. At least, as far as my test, there are no problem.

Thus, just call dispatch_source_set_timer for a new interval.

dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, refreshRate * NSEC_PER_SEC), refreshRate * NSEC_PER_SEC, refreshRate * NSEC_PER_SEC);
0

精彩评论

暂无评论...
验证码 换一张
取 消