Grand Central Dispatch替代使用NSTimer的方法-多次无效 [英] Grand Central Dispatch alternative to using an NSTimer - invalidating multiple times

查看:62
本文介绍了Grand Central Dispatch替代使用NSTimer的方法-多次无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用的 dispatch_source_t 出现问题.我想用它来延迟 PHChange 的处理5秒钟,因为 PHChange 可以在短时间内多次发生.我将不胜感激.本质上,我想取消以前的 dispatch_source_t 计时器,就像 NSTimer 一样.

I have an issue with a dispatch_source_t I'm trying to use. I'm wanting to use it to delay the processing of a PHChange for 5 seconds because a PHChange can happen multiple times in a short span. I'd appreciate any help offered. Essentially I want to cancel the prior dispatch_source_t timer almost like an NSTimer.

@property (nonatomic, strong) dispatch_source_t libraryChangedTimer;

dispatch_source_t CreateTimerDispatchSource(uint64_t interval, uint64_t leeway, dispatch_queue_t queue, dispatch_block_t block)
{
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

    if (timer)
    {
        dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);

        dispatch_source_set_event_handler(timer, block);

        dispatch_resume(timer);
    }

    return timer;
}

- (void)libraryChanged:(PHChange *)changeInstance
{
    NSLog(@"Called immediately and it shouldn't");
}

- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
    if (self.libraryChangedTimer)
    {
        dispatch_source_cancel(self.libraryChangedTimer);

        self.libraryChangedTimer = CreateTimerDispatchSource(5ull * NSEC_PER_SEC, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^
        {
            [self libraryChanged:changeInstance];
            dispatch_source_cancel(self.libraryChangedTimer);
        });
    }
    else
    {
        self.libraryChangedTimer = CreateTimerDispatchSource(5ull * NSEC_PER_SEC, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^
        {
            [self libraryChanged:changeInstance];
            dispatch_source_cancel(self.libraryChangedTimer);
        });
    }
}

推荐答案

我使用 dispatch_after 代码非常简单地解决了这个问题:

I figured this out quite simply with using dispatch_after Code:

dispatch_source_t CreateTimerDispatchSource(uint64_t interval, uint64_t leeway, dispatch_queue_t queue, dispatch_block_t block)
{
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

    if (timer)
    {
        dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), DISPATCH_TIME_FOREVER, leeway);

        dispatch_source_set_event_handler(timer, block);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, interval), queue,^
        {
            dispatch_resume(timer);
        });
    }

    return timer;
}

- (void)libraryChanged:(PHChange *)changeInstance
{
    // Do something 
}

- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
    if (self.libraryChangedTimer)
    {
        dispatch_source_cancel(self.libraryChangedTimer);

        self.libraryChangedTimer = CreateTimerDispatchSource(5ull * NSEC_PER_SEC, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^
        {
            [self libraryChanged:changeInstance];
            dispatch_source_cancel(self.libraryChangedTimer);
            self.libraryChangedTimer = nil;
        });
    }
    else
    {
        self.libraryChangedTimer = CreateTimerDispatchSource(5ull * NSEC_PER_SEC, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^
        {
            [self libraryChanged:changeInstance];
            dispatch_source_cancel(self.libraryChangedTimer);
            self.libraryChangedTimer = nil;
        });
    }
}

这篇关于Grand Central Dispatch替代使用NSTimer的方法-多次无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆