ASi

GCD の timer

fire した後でも cancel すると cancel handler が呼ばれる。fire のハンドラからでも cancel できる。

dispatch_source_t createTimer(int msec, void(^fired)(), void(^canceled)()){
    dispatch_source_t timersource = dispatch_source_create(
        DISPATCH_SOURCE_TYPE_TIMER,
        /* handle */ 0, /* mask */ 0,
        dispatch_get_main_queue());
    dispatch_source_set_timer(timersource, 
        dispatch_time(DISPATCH_TIME_NOW, msec * NSEC_PER_MSEC),
        /* this means oneshot */DISPATCH_TIME_FOREVER, /* leeway */ 0);
    dispatch_source_set_event_handler(timersource, fired);
    if (canceled){
        dispatch_source_set_cancel_handler(timersource, canceled);
    }
    return timersource;
}


    __block dispatch_source_t timer = createTimer(5000, ^{
    
        // do fired proceadure
    
        dispatch_source_cancel(timer);
        
    }, ^{
    
        // do cleanup

        timer = nil;
    });