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);
精彩评论