本文接着上一篇讲。主要讲:dispatch_source。
dispatch_source主要用户监听事件,可以监听如下事件
DISPATCH_SOURCE_TYPE_DATA_ADDDISPATCH_SOURCE_TYPE_DATA_ORDISPATCH_SOURCE_TYPE_MACH_RECVDISPATCH_SOURCE_TYPE_MACH_SENDDISPATCH_SOURCE_TYPE_PROCDISPATCH_SOURCE_TYPE_READDISPATCH_SOURCE_TYPE_SIGNALDISPATCH_SOURCE_TYPE_TIMERDISPATCH_SOURCE_TYPE_VNODEDISPATCH_SOURCE_TYPE_WRITEDISPATCH_SOURCE_TYPE_MEMORYPRESSURE
比较常用的就是实现Timer与自定义事件(DISPATCH_SOURCE_TYPE_DATA_ADD、DISPATCH_SOURCE_TYPE_DATA_OR)。
一、实现timer
使用NSTimer会有循环引用的问题,使用dispatch_source就不会有问题,代码如下
__block NSInteger count = 0; dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.f * NSEC_PER_SEC, 0 * NSEC_PER_SEC); dispatch_source_set_event_handler(timer, ^{ NSLog(@"count == %li", count++); }); dispatch_resume(timer);
需要注意的是dispatch_source_t不会创建之后自动执行,需要显示的调用dispatch_resume才会执行,而且调用resume之后会立刻执行一次。
二、监听用户自定义事件
DISPATCH_SOURCE_TYPE_DATA_ADD会对用dispatch_source_merge_data提交的数据进行累加,DISPATCH_SOURCE_TYPE_DATA_OR则是对提交的数据进行或运算。示例代码如下
@interface ViewController10 ()@property (nonatomic, strong) dispatch_source_t source;@end@implementation ViewController10- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"dispatch_source_t 实现自定义事件"); //模拟器第一次执行会有卡顿,真机不会,俺也不知道原因 __block NSInteger total = 0; dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_queue_create("com.wk.serialQueue", DISPATCH_QUEUE_CONCURRENT)); dispatch_source_set_event_handler(source, ^{ NSInteger result = dispatch_source_get_data(source); total += result; NSLog(@"total = %li", total); }); dispatch_source_set_cancel_handler(source, ^{ NSLog(@"取消了派发源"); }); dispatch_resume(source); self.source = source; dispatch_queue_t global = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); dispatch_semaphore_t semaphore = dispatch_semaphore_create(10); for (int i = 0; i < 100; i++) { dispatch_async(global, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_source_merge_data(source, 1); sleep(1.f); dispatch_semaphore_signal(semaphore); }); }}- (void)dealloc{ dispatch_source_cancel(self.source);}
dispatch_source_cancel可以取消派发源,使派发员不在监听指定事件 你可以在这里下载