GCD 定时器

GCD 中除了主要的Dispatch Queue, 还有Dispatch Source, Dispatch I/O, Dispatch Data, 不过这些基本上没有使用。使用Dispatch Source用得最多的就是定时器功能。 在IM中,socket超时等情况就可以使用下面这个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());

dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15ull * NSEC_PER_SEC));
dispatch_source_set_timer(timer, start, DISPATCH_TIME_FOREVER, (int64_t)(1ull * NSEC_PER_SEC));

dispatch_source_set_event_handler(timer, ^{
NSLog(@"唤醒了定时器");
dispatch_source_cancel(timer);
});

dispatch_source_set_cancel_handler(timer, ^{
NSLog(@"取消");
});

dispatch_resume(timer);

使用dispatch_source_create创建一个dispatch_source_t类型的timer。经过指定的时间把处理任务追加到住队列中。

使用dispatch_source_set_timer指定15秒后执行任务,不允许重复,允许延迟1秒。

dispatch_source_set_event_handler定时器指定时间内处理的任务。

dispatch_source_set_cancel_handler指定取消时的处理任务

最后使用dispatch_resume启动定时器。

Dispatch Source 中是可以取消任务的,而Dispatch Queue中是没有的,只有挂起。

完整的定时器

会重复执行,直到调用invalidate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@interface LZTimer ()

@property (nonatomic, assign) dispatch_source_t source;

@property (nonatomic, copy) dispatch_block_t block;

@end

@implementation LZTimer

+ (LZTimer *)timerRepeatintWithTimeInterval:(NSTimeInterval)seconds block:(dispatch_block_t)block {

NSParameterAssert(seconds);
NSParameterAssert(block);

LZTimer *timer = [[self alloc] init];
timer.block = block;
timer.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());

uint64_t nsec = (uint64_t)(seconds * NSEC_PER_SEC);

dispatch_source_set_timer(timer.source, dispatch_time(DISPATCH_TIME_NOW, nsec), nsec, 0);

dispatch_source_set_event_handler(timer.source, block);

dispatch_resume(timer.source);

return timer;
}

- (void)invalidate {
if (self.source) {
dispatch_source_cancel(self.source);
self.source = nil;
}
self.block = nil;
}

- (void)dealloc {
[self invalidate];
}

- (void)fire {
self.block();
}

@end
坚持原创技术分享,您的支持将鼓励我继续创作!