天天看点

Dispatch Source

1、它有什么用

       dispatch source 的作用是负责监听事件,先看看它的构造函数。

[objc] view plaincopy

Dispatch Source
Dispatch Source
  1. dispatch_source_create(dispatch_source_type_t type,  
  2. uintptr_t handle,  
  3. unsigned long mask,  
  4. dispatch_queue_t queue);  

       第1个参数:要监听的事件类型

       第2个参数:可以理解为句柄、索引或id,假如要监听进程,需要传入进程的ID

       第3个参数:根据参数2,可以理解为描述,提供更详细的描述,让它知道具体要监听什么

       第4个参数:当事件发生时,将block添加至哪个队列来执行

2、可监听事件的类型

       DISPATCH_SOURCE_TYPE_TIMER        定时响应

        DISPATCH_SOURCE_TYPE_SIGNAL      接收到UNIX信号时响应

        DISPATCH_SOURCE_TYPE_READ   IO操作,如对文件的操作、socket操作的读响应

        DISPATCH_SOURCE_TYPE_WRITE     IO操作,如对文件的操作、socket操作的写响应   

        DISPATCH_SOURCE_TYPE_VNODE    文件状态监听,文件被删除、移动、重命名

        DISPATCH_SOURCE_TYPE_PROC  进程监听,如进程的退出、创建一个或更多的子线程、进程收到UNIX信号

        DISPATCH_SOURCE_TYPE_MACH_SEND

        DISPATCH_SOURCE_TYPE_MACH_RECV   上面2个都属于Mach相关事件响应

        DISPATCH_SOURCE_TYPE_DATA_ADD

        DISPATCH_SOURCE_TYPE_DATA_OR          上面2个都属于自定义的事件,并且也是有自己来触发

3、怎么使用

 (一)自定义事件(DISPATCH_SOURCE_TYPE_DATA_ADD、DISPATCH_SOURCE_TYPE_DATA_OR),先看代码

Dispatch Source
Dispatch Source
  1. dispatch_source_t source =dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());  
  2. dispatch_source_set_event_handler(source,^{  
  3.        NSLog(@"监听函数:%lu",dispatch_source_get_data(source));  
  4. });  
  5. dispatch_resume(source);  
  6. dispatch_queue_t myqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);  
  7. dispatch_async(myqueue, ^ {  
  8.       int i;  
  9.       for(i = 0;i<</span>4;i++){  
  10.          dispatch_source_merge_data(source,i);  
  11.       }  

首先使用dispatch_source_create函数创建 dispatchsource,第1个参数表示它是一个自定义的_ADD类型的监听,具体作用后面说,2、3参数这里面没有作用设置为0即可,第4个参数 表示一旦事件触发就将要执行的代码块添加到主队列中执行,接着我们使用dispatch_source_set_event_handler函数为这个监 听设置事件的源和响应体,第1个参数表示这个监听是响应用户自定义事件的,也就是我们上面定义的dispatchsource,第2个参数是负责响应的代 码块。很有意思的是当我们创建监听后,这个监听默认是挂起的,需要手动恢复,所以我们使用dispatch_resume函数恢复这个监听,为了测试这个 监听,我们后面又通过for循环触发事件,触发事件的函数就是dispatch_source_merge_data,这个函数负责触发自定义事件,第1 个参数表示要触发哪个监听,第2个参数是向监听传入一个unsigned long 类型的值, 我们这里传入循环的索引,好了,整体来看这段程序,dispatch_source_merge_data函数会被执行4次,并分别传入0、1、2、3这 4个值,既然dispatch_source_merge_data负责触发事件,那么我们在监听里面的响应体应该会监听到,结果也确实监听到了,但是并 不是我们想象的那样打印4次,而是只打印了一次,打印结果是4次传入值相加的和,也就是6,这就是 DISPATCH_SOURCE_TYPE_DATA_ADD参数的作用,这个监听在创建之初就被设置为自定义监听,并且会把监听结果相加,然后统一响 应。这里你应该会奇怪,既然结果会相加并统一响应,那跟触发的时候加好,然后触发一次有什么区别呢,好吧,我们把触发事件的for循环改一下,然后再运 行,看看会发生什么

Dispatch Source
Dispatch Source
  1. for(i = 0;i<</span>4;i++){  
  2.     dispatch_source_merge_data(source,i);  
  3.     [NSThread sleepForTimeInterval:0.0001];  
  4. }