我对自己制定的 GCD 解决方案有疑问。我有一个在后台运行的线程,它在给定的时间间隔内更新应用程序。为此,我使用计时器。
但是,如果用户想要更改此间隔,我会调用
dispatch_source_cancel(timer);
定义为
dispatch_source_set_cancel_handler(timer, ^{
dispatch_release(timer);
});
然后重新启动线程。当第二次更改间隔时,应用程序崩溃。即使我确实使用新的间隔重新创建了计时器。
我可以避免释放计时器,但这样我就会有内存韭菜。
有什么建议吗?该怎么办?
编辑: 定时器是这样创建的
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
});
最佳答案
我认为这不是答案。 dispatch_source_cancel 不会立即同步取消。
- mandispatch_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).
因此,如果 autoRefreshQueue 是全局队列,则重新启动线程可能会同时调用这些 block 。
你是如何重新启动线程的?
已编辑:
但是,引用资料或手册中没有提到对同一调度源调用dispatch_source_set_timer两次(或多次),libdispatch/src/source.c中的dispatch_source_set_timer似乎可以。至少,据我测试,没有问题。
因此,只需调用dispatch_source_set_timer 即可设置新的时间间隔。
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, refreshRate * NSEC_PER_SEC), refreshRate * NSEC_PER_SEC, refreshRate * NSEC_PER_SEC);
关于iphone - Grand Central Dispatch 与dispatch_release 相关的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6200387/